]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-20010228 v20010228
authorWietse Venema <wietse@porcupine.org>
Wed, 28 Feb 2001 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 15:51:27 +0000 (15:51 +0000)
156 files changed:
postfix/.indent.pro
postfix/0README
postfix/COMPATIBILITY
postfix/DEBUG_README
postfix/FILTER_README
postfix/HISTORY
postfix/INSTALL
postfix/INSTALL.sh
postfix/LDAP_README
postfix/LINUX_README [moved from postfix/BEWARE with 74% similarity]
postfix/LMTP_README
postfix/LMTP_README.old [deleted file]
postfix/PCRE_README
postfix/RELEASE_NOTES
postfix/RESTRICTION_CLASS
postfix/SASL_README
postfix/TODO
postfix/UUCP_README
postfix/VIRTUAL_README [deleted file]
postfix/conf/access
postfix/conf/main.cf
postfix/conf/master.cf
postfix/conf/postfix-script-nosgid
postfix/conf/postfix-script-sgid
postfix/conf/sample-ldap.cf
postfix/conf/sample-local.cf
postfix/conf/sample-misc.cf
postfix/conf/sample-smtpd.cf
postfix/conf/sample-virtual.cf [new file with mode: 0644]
postfix/html/Makefile.in
postfix/html/access.5.html
postfix/html/backstage.html
postfix/html/basic.html
postfix/html/delivering.html
postfix/html/error.8.html
postfix/html/faq.html
postfix/html/index.html
postfix/html/lmtp.8.html
postfix/html/local.8.html
postfix/html/postdrop.1.html
postfix/html/qmgr.8.html
postfix/html/smtpd.8.html
postfix/html/trivial-rewrite.8.html
postfix/html/uce.html
postfix/makedefs
postfix/man/Makefile.in
postfix/man/man5/access.5
postfix/man/man8/lmtp.8
postfix/man/man8/local.8
postfix/man/man8/smtpd.8
postfix/mantools/README
postfix/mantools/man2html [new file with mode: 0755]
postfix/mantools/postlink [new file with mode: 0755]
postfix/proto/access
postfix/src/dns/dns_lookup.c
postfix/src/dns/dns_strtype.c
postfix/src/flush/flush.c
postfix/src/global/Makefile.in
postfix/src/global/deliver_flock.c
postfix/src/global/dot_lockfile.c
postfix/src/global/mail_params.c
postfix/src/global/mail_params.h
postfix/src/global/mail_queue.c
postfix/src/global/mail_version.h
postfix/src/global/mkmap_open.c
postfix/src/global/mynetworks.c
postfix/src/global/own_inet_addr.c
postfix/src/global/own_inet_addr.h
postfix/src/global/peer_name.c
postfix/src/lmtp/Makefile.in
postfix/src/lmtp/lmtp.c
postfix/src/lmtp/lmtp_proto.c
postfix/src/lmtp/lmtp_trouble.c
postfix/src/local/Makefile.in
postfix/src/local/local.c
postfix/src/local/maildir.c
postfix/src/master/master.c
postfix/src/master/master_sig.c
postfix/src/pipe/pipe.c
postfix/src/postconf/Makefile.in
postfix/src/postconf/local_table.h [deleted file]
postfix/src/postconf/local_vars.h [deleted file]
postfix/src/postconf/postconf.c
postfix/src/postsuper/postsuper.c
postfix/src/qmgr/qmgr.c
postfix/src/qmgr/qmgr_bounce.c
postfix/src/qmgr/qmgr_deliver.c
postfix/src/qmgr/qmgr_entry.c
postfix/src/qmgr/qmgr_message.c
postfix/src/sendmail/sendmail.c
postfix/src/smtp/Makefile.in
postfix/src/smtp/smtp.c
postfix/src/smtp/smtp_addr.c
postfix/src/smtp/smtp_sasl_proto.c
postfix/src/smtpd/Makefile.in
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd.h
postfix/src/smtpd/smtpd_check.c
postfix/src/smtpd/smtpd_peer.c
postfix/src/smtpstone/smtp-sink.c
postfix/src/util/Makefile.in
postfix/src/util/dict.c
postfix/src/util/dict.h
postfix/src/util/dict_alloc.c [new file with mode: 0644]
postfix/src/util/dict_db.c
postfix/src/util/dict_db.h
postfix/src/util/dict_dbm.c
postfix/src/util/dict_dbm.h
postfix/src/util/dict_debug.c [new file with mode: 0644]
postfix/src/util/dict_env.c
postfix/src/util/dict_env.h
postfix/src/util/dict_ht.c
postfix/src/util/dict_ht.h
postfix/src/util/dict_ldap.c
postfix/src/util/dict_ldap.h
postfix/src/util/dict_mysql.c
postfix/src/util/dict_mysql.h
postfix/src/util/dict_ni.c
postfix/src/util/dict_ni.h
postfix/src/util/dict_nis.c
postfix/src/util/dict_nis.h
postfix/src/util/dict_nisplus.c
postfix/src/util/dict_nisplus.h
postfix/src/util/dict_open.c
postfix/src/util/dict_pcre.c
postfix/src/util/dict_pcre.h
postfix/src/util/dict_regexp.c
postfix/src/util/dict_regexp.h
postfix/src/util/dict_tcp.c
postfix/src/util/dict_tcp.h
postfix/src/util/dict_unix.c
postfix/src/util/dict_unix.h
postfix/src/util/duplex_pipe.c
postfix/src/util/get_hostname.c
postfix/src/util/inet_addr_local.c
postfix/src/util/inet_addr_local.h
postfix/src/util/iostuff.h
postfix/src/util/rand_sleep.c [new file with mode: 0644]
postfix/src/util/safe_open.c
postfix/src/util/sane_socketpair.c [new file with mode: 0644]
postfix/src/util/sane_socketpair.h [new file with mode: 0644]
postfix/src/util/sane_time.c [new file with mode: 0644]
postfix/src/util/sane_time.h [new file with mode: 0644]
postfix/src/util/sys_defs.h
postfix/src/util/valid_hostname.c
postfix/src/util/valid_hostname.h
postfix/src/virtual/.indent.pro [deleted symlink]
postfix/src/virtual/Makefile.in [deleted file]
postfix/src/virtual/deliver_attr.c [deleted file]
postfix/src/virtual/mailbox.c [deleted file]
postfix/src/virtual/maildir.c [deleted file]
postfix/src/virtual/recipient.c [deleted file]
postfix/src/virtual/unknown.c [deleted file]
postfix/src/virtual/virtual [deleted file]
postfix/src/virtual/virtual.c [deleted file]
postfix/src/virtual/virtual.h [deleted file]

index 7223e9d27269c0e843019d4562f817ac81f5886d..c35b4962ff877e69d2556ae590744d51a8930f57 100644 (file)
@@ -27,6 +27,7 @@
 -TDICT_ENV
 -TDICT_HT
 -TDICT_LDAP
+-TDICT_DEBUG
 -TDICT_MYSQL
 -TDICT_NI
 -TDICT_NIS
index c399b25190a5a9307e8c3cc077b8cf001bdb8e17..8538cebe205d73c804239477c4f855e61821383e 100644 (file)
@@ -2,8 +2,13 @@ Purpose of this document
 ========================
 
 This document provides a road map of the Postfix mail system source
-code distribution.  I suggest that you take a few minutes to read
-this file, and then proceed with the INSTALL instructions.
+code distribution.  I suggest that you
+
+- take a few minutes to read this file,
+
+- review the RELEASE_NOTES file for incompatible changes,
+
+- and then proceed with the INSTALL instructions.
 
 Introduction
 ============
@@ -21,9 +26,7 @@ Purpose of the Postfix mail system
 ==================================
 
 Postfix aims to be an alternative to the widely-used sendmail
-program.  Sendmail is responsible for 70% of all e-mail delivered
-on the Internet.  With an estimated 100 million users, that's an
-estimated 10 billion (10^10) messages daily. A stunning number.
+program.
 
 Although IBM supported the Postfix development, it abstains from
 control over its evolution. The goal is to have Postfix installed
@@ -40,7 +43,6 @@ On-line resources devoted to the Postfix mail system
 Web sites:
 
     http://www.postfix.org/            current release information
-    http://www.ibm.com/alphaworks/     original distribution site (obsolete)
 
 Mail addresses (PLEASE send questions to the mailing list)
 
@@ -72,15 +74,6 @@ you are welcome to send a postcard to:
 Roadmap of the Postfix source distribution
 ==========================================
 
-Point your browser at html/index.html for Postfix documentation,
-for manual pages, and for the unavoidable Postfix FAQ. Expect to
-see updated versions on-line at http://www.postfix.org/
-
-Point your MANPATH environment variable at the `man' directory (use
-an absolute path) for UNIX-style on-line manual pages.  These pages
-are also available through the HTML interface, which allows you to
-navigate faster.
-
 The RELEASE_NOTES file describes new features, and lists incompatible
 changes with respect to previous Postfix versions.
 
@@ -92,10 +85,17 @@ not yet implement, and how well it works with other software.
 
 The HISTORY file gives a detailed log of changes to the software.
 
+Point your browser at html/index.html for Postfix documentation,
+for manual pages, and for the unavoidable Postfix FAQ. Expect to
+see updated versions on-line at http://www.postfix.org/
+
+Point your MANPATH environment variable at the `man' directory (use
+an absolute path) for UNIX-style on-line manual pages.  These pages
+are also available through the HTML interface, which allows you to
+navigate faster.
+
 The PORTING file discusses how to go about porting Postfix to other
-UNIX platforms. Some people are looking into a port to Windows NT.
-We'll see. This software uses every trick in the book that I learned
-about UNIX.
+UNIX platforms.
 
 The TODO file lists things that still need to be done. If you want
 to set your teeth into one of those problems, drop me a note at
@@ -146,6 +146,7 @@ Postfix daemons:
     src/smtp/          SMTP client
     src/smtpd/         SMTP server
     src/trivial-rewrite/ Address rewriting and resolving
+    src/virtual/       virtual mailbox-only delivery agent
 
 Test programs:
 
index 4c161b9208df7c48a7cc57908519ab2fc9ec3b4b..bb754a363b156510168de80914fa9d55fde07fb2 100644 (file)
@@ -7,20 +7,21 @@
 aliases                yes (can enable/disable mail to /file or |command)
 bare newlines  yes (but will send CRLF)
 blacklisting   yes (client name/addr; helo hostname; mail from; rcpt to)
-content filter no
+content filter yes
 db tables      yes (compile time option)
 dbm tables     yes (compile time option)
 delivered-to   yes
-dsn            not yet
+dsn            not yet (bounces have DSN form)
 errors-to:     yes
 esmtp          yes
 etrn support   yes (uses per-destination log or flushes entire queue)
-fcntl locking  yes (compile time)
-flock locking  yes (compile time)
+fcntl locking  yes (runtime configurable)
+flock locking  yes (runtime configurable)
 home mailbox   yes
 ident lookup   no
 ldap tables    yes (contributed)
-luser relay    not yet
+luser relay    yes
+lmtp support   yes (client)
 m4 config      no
 mail to command        yes (configurable for .forward, aliases, :include:)
 mail to file   yes (configurable for .forward, aliases, :include:)
@@ -30,6 +31,7 @@ mailq         yes
 majordomo      yes (edit approve script to delete /delivered-to/i)
 mime conversion        not yet; postfix uses just-send-eight
 missing <>     yes (most common address forms)
+mysql tables   yes (contributed)
 netinfo tables yes (contributed)
 newaliases     yes (main alias database only)
 nis tables     yes
@@ -38,8 +40,10 @@ pipeline option      yes (server and client)
 pop/imap       yes (with third-party daemons that use /var[/spool]/mail)
 rbl support    yes
 return-receipt:        not yet
+sasl support   yes (compile time option)
+sendmail -bt   no
 sendmail -q    yes
-sendmail -qRxxx        no
+sendmail -qRxxx        yes
 sendmail -qSxxx        no
 sendmail -qtime        ignored
 sendmail -v    no
@@ -49,7 +53,7 @@ smarthost     yes
 tcp wrapper    no (use built-in blacklist facility)
 user+extension yes (also: .forward+extension)
 user-extension yes (also: .forward-extension)
-user.lock      yes (compile time)
+user.lock      yes (runtime configurable)
 uucp support   yes (sends user@domain recipients)
 virtual domains        yes
 year 2000 safe yes
index 4e8f2cea25f1b6f646baba70d89c41e3a0d1d5c3..cd2593eb682e3974679857fcd37e98cd39e3c4c3 100644 (file)
@@ -18,8 +18,21 @@ from or to the loopback interface:
 
 You can specify one or more hosts, domains, addresses or net/masks.
 
-3 - Making daemon programs more verbose
-=======================================
+2b - Record the SMTP connection with a sniffer
+==============================================
+
+This example uses tcpdump. In order to record a conversation you
+need to specify a large enough buffer or else you will miss some
+or all of the packet payload.
+
+    tcpdump -w /file/name -s 2000 host hostname and port 25
+
+Run this for a while, stop with Ctrl-C when done. To view the data
+use a binary viewer, or use my tcpdumpx utility that is available
+from ftp://ftp.porcupine.org/pub/debugging.
+
+3 - Making Postfix daemon programs more verbose
+===============================================
 
 Append one or more -v options to selected daemon definitions in
 /etc/postfix/master.cf and type "postfix reload". This will cause
index 243c2f4c95bf5dde4321623d66487773a7801f35..adb7d28fdcda68a29fb75a2484fe7bc31a4b4a13 100644 (file)
@@ -1,6 +1,6 @@
 This is a very first implementation of Postfix content filtering.
 A Postfix content filter receives unfiltered mail from Postfix and
-re-injects filtered mail back into Postfix.
+either bounces the mail or re-injects filtered mail back into Postfix.
 
 It involves an incompatible change to queue file formats.  Older
 Postfix versions will reject mail that needs to be content filtered,
@@ -24,32 +24,34 @@ The example assumes that only mail arriving via SMTP needs to be
 content filtered.
 
       ..................................
-      .            Postfix             .
-   ------smtpd \                /local-----
-      .         -cleanup->queue-       .
-   -----pickup /                \smtp------
-   ^  .                        |       .
-   |  .                         \pipe-----+
+      :            Postfix             :
+   ----->smtpd \                /local---->
+      :         -cleanup->queue-       :
+   ---->pickup /                \smtp----->
+   ^  :                        |       :
+   |  :                         \pipe-----+
    |  ..................................  |
    |                                      |
    |                                      |
    +------sendmail<-------filter<---------+
 
-Create a dedicated local user account called "filter".  The user
-will never log in, and can be given a "*" password and non-existent
-shell and home.
+1 - Create a dedicated local user account called "filter".  The
+    user will never log in, and can be given a "*" password and
+    non-existent shell and home directory. This user handles all
+    potentially dangerous mail content - that is why it should be
+    a separate account.
 
-Create a directory /var/spool/filter that is accessible only to
-the "filter" user. This is where the content filtering will store
-its temporary files.
+2 - Create a directory /var/spool/filter that is accessible only
+    to the "filter" user. This is where the content filtering will
+    store its temporary files.
 
-Define a content filtering entry in the Postfix master file:
+3 - Define a content filtering entry in the Postfix master file:
 
     /etc/postfix/master.cf:
-       filter    unix  -       n       n       -       -       pipe
-           user=filter argv=/some/where/filter -f ${sender} -- ${recipient}
+      filter    unix  -       n       n       -       -       pipe
+        flags=R user=filter argv=/some/where/filter -f ${sender} -- ${recipient}
 
-The filter program can start out as a simple shell script like this:
+The /some/where/filter program can be a simple shell script like this:
 
     #!/bin/sh
 
@@ -85,20 +87,11 @@ content is OK, it is given as input to Postfix sendmail, and the
 exit status of the filter command is whatever exit status Postfix
 sendmail produces.
 
-The problem with content filters like this is that they are not
-very robust, because the software does not talk a well-defined
-protocol with Postfix. If the filter shell script aborts because
-the shell runs into some memory allocation problem, the script will
-not produce a nice exit status as per /usr/include/sysexits.h and
-mail will probably bounce. The same lack of robustness is possible
-when the content filtering software itself runs into a resource
-problem.
-
 I suggest that you play with this script for a while until you are
-satisfied with the results. Run it as root or as the filter user,
-with a real message (headers+body) as input:
+satisfied with the results. Run it as the filter user, with a real
+message (headers+body) as input:
 
-    # /some/where/filter -f sender recipient... <message-file
+    % /some/where/filter -f sender recipient... <message-file
 
 Turn on content filtering for mail arriving via SMTP only, by
 appending "-o content_filter=filter:dummy" to the master.cf
@@ -111,9 +104,17 @@ entry that defines the Postfix SMTP server:
 The content_filter configuration parameter accepts the same
 syntax as the right-hand side in a Postfix transport table.
 
-Postfix snapshot-20000529 requires that you specify a dummy
-destination as shown in the example.  This is no longer necessary
-with later Postfix versions.
+Simple content filter limitations
+=================================
+
+The problem with content filters like the one above is that they
+are not very robust, because the software does not talk a well-defined
+protocol with Postfix. If the filter shell script aborts because
+the shell runs into some memory allocation problem, the script will
+not produce a nice exit status as per /usr/include/sysexits.h and
+mail will probably bounce. The same lack of robustness is possible
+when the content filtering software itself runs into a resource
+problem.
 
 Advanced content filtering example
 ===================================
@@ -132,20 +133,20 @@ port 10025 that receives mail via the SMTP protocol, and that
 submits mail back into Postfix via localhost port 10026.
 
       ..................................
-      .            Postfix             .
-   ------smtpd \                /local-----
-      .         -cleanup->queue-       .
-   -----pickup /    ^       |   \smtp------
-      .             |       v          .
-      .           smtpd    smtp        .
-      .           10026     |          .
+      :            Postfix             :
+   ----->smtpd \                /local---->
+      :         -cleanup->queue-       :
+   ---->pickup /    ^       |   \smtp----->
+      :             |       v          :
+      :           smtpd    smtp        :
+      :           10026     |          :
       ......................|...........
                     ^       |
                     |       v
                 ....|............
-                .   |     10025 .
-                .   filtering   .
-                .               .
+                :   |     10025 :
+                :   filter      :
+                :               :
                 .................
 
 To enable content filtering in this manner, specify in main.cf a
@@ -174,12 +175,13 @@ up to 10 content filtering processes on demand:
 
 "filter" is a dedicated local user account.  The user will never
 log in, and can be given a "*" password and non-existent shell and
-home.
+home directory.  This user handles all potentially dangerous mail
+content - that is why it should be a separate account.
 
-The spawn server is part of Postfix but is not installed by default.
-Edit the top-level Makefile.in file, run "make makefiles", "make",
-and "make install". The manual page isn't installed by default,
-either. See the spawn.c source file.
+In the above example, Postfix listens on port localhost:10025.  If
+you want to have your filter listening on port localhost:10025
+instead of Postfix, then you must run your filter as a stand-alone
+program.
 
 The /some/where/filter command is most likely a PERL script. PERL
 has modules that make talking SMTP easy. The command-line specifies
@@ -192,7 +194,8 @@ it can be used with other mailers too, which is a nice spin-off.
 The simplest content filter just copies SMTP commands and data
 between its inputs and outputs. If it has a problem, all it has to
 do is to reply to an input of `.' with `550 content rejected', and
-to disconnect its output side instead of sending `.'.
+to disconnect without sending `.' on the connection that injects
+mail back into Postfix.
 
 The job of the content filter is to either bounce mail with a
 suitable diagnostic, or to feed the mail back into Postfix through
index b254bea66ed170247915dc288b9ebe70293025b2..4a6572894117dbf9096a8f406731d62c83257b8a 100644 (file)
@@ -3987,13 +3987,6 @@ Apologies for any names omitted.
        Bugfix: the code for masquerade_exceptions was case sensitive.
        Reported by Eduard Vopicka.  File: cleanup/cleanup_masquerade.c.
 
-20000526
-
-       Feature: experimental queue manager by Patrik Rak with a
-       fancy pre-emptive scheduling algorithm that improves delivery
-       performance of mail with few recipients. This queue manager
-       is made available as "nqmgr".
-
 20000528
 
        Feature: the SMTP client SASL password file can contain
@@ -4026,9 +4019,6 @@ Apologies for any names omitted.
        Added a simple shell-script based content filtering example
        to the FILTER_README file.
 
-       Content filtering support for nqmgr by Patrik Rak.  File:
-       nqmgr/qmgr_message.c.
-
        Renamed "content inspection" etc. to "content filtering"
        in anticipation of a new hook for content inspection that
        only inspects mail without re-injecting it into Postfix.
@@ -4261,9 +4251,6 @@ Apologies for any names omitted.
 
 20000922
 
-       nqmgr update from Patrik Rak for the changed queue manager
-       to delivery agent protocol.
-
        Lame feature: syslog_facility parameter to control where
        syslogd sends Postfix logging (default: syslog_facility =
        mail).  However, errors during command-line parsing are
@@ -4475,11 +4462,6 @@ Apologies for any names omitted.
        Bugfix: the recipient home directory test broke mailbox_transport
        support for non-UNIX recipients.  File:  local/recipient.c.
 
-20001117
-
-       Robustness: additional integrity tests for the nqmgr by
-       Patrik Rak. File: nqmgr/qmgr_message.c.
-
 20001118
 
        Bugfix: the new LDAP client code did not work properly if
@@ -4733,7 +4715,6 @@ Apologies for any names omitted.
 
        Feature: SASL support for the LMTP client. Recent CYRUS
        software requires this for Postfix over TCP sockets.
-       This was just a cloning operation.
 
 20010120
 
@@ -4745,5 +4726,196 @@ Apologies for any names omitted.
 
 20010121
 
+       Workaround: specify "broken_sasl_auth_clients = yes" in
+       order to support old Microsoft clients that implement
+       a non-standard version of RFC 2554 (AUTH command).
+
        Workaround: Lotus Domino 5.0.4 violates RFC 2554 and replies
        to EHLO with AUTH=LOGIN. File: smtp/smtp_proto.c.
+
+20010125
+
+       Code cleanup: wrote creator/destructor for dictionary
+       objects that provides default methods that trap all attempts
+       to perform an unimplemented operation. Based on an ansatz
+       by Laurent Wacrenier (teaser.fr).  Files: util/dict*.[hc].
+
+       Code cleanup: INSTALL.sh does not ask questions when stdin
+       is not connected to a tty (as in: make install</dev/null).
+       To automate a customized install, the script imports
+       environment variables for install_root etc.
+
+20010127
+
+       Workaround: randomize the delay between attempts to lock
+       a file, so that multiple bounce or defer servers are less
+       likely to retry all at the same time.  likely.  File:
+       util/rand_sleep.c, global/deliver_flock.c, global/dot_lockfile.c.
+
+20010128
+
+       Code cleanup: complaints about invalid or numeric hostnames
+       either provide specific context or are removed as redundant.
+       Files:  util/valid_hostname.c dns/dns_lookup.c.
+
+       Code cleanup: new mailbox_size_limit parameter (default:
+       20MB).  Until now, the mailbox size limit was the same as
+       the message size limit, due to artefact of implementation.
+       Files: global/mail_params.h, local/local.c.
+
+       Bugfix: fix for the ldap_domains parameter, both semantics
+       and documentation by LaMont Jones. Files:  LDAP_README,
+       conf/sample-ldap.cf, util/dict_ldap.c.
+
+20010129
+
+       Cleanup: clarified documentation and boundary cases in the
+       random_sleep() routine.
+
+       Bugfix: the MISSING_USLEEP feature was used backwards.
+       Patrik Rak. File: util/random_sleep.c.
+
+20010130
+
+       Workaround: Linux usleep() is void, BSD/Solaris usleep()
+       returns int, don't use it. File util/random_sleep.c.
+
+       Made local maildir bounce/defer handling mode consistent
+       with local mailbox delivery. File local/maildir.c.
+
+       The smtp client now defers delivery when all MX hosts have
+       no A record. File: smtp/smtp_addr.c
+
+       Bundled the man2html and postlink quick hacks so people
+       can do their own manual page processing. See scripts in
+       the mantools directory.
+
+       Documentation: updated the reference to sendmail in the
+       html/index.html page.
+
+       Documentation: added note about the Cisco PIX "fixup smtp"
+       bug that causes mail delivery problems when "." and "CRLF"
+       arrive in separate packets. File:  html/faq.html.
+
+20010201
+
+       Bugfix: another missing initialization in the mysql client.
+       File: util/dict_mysql.c.
+
+       Bumped the default mailbox file size limits to 50MB.
+
+20010202
+
+       Bugfix: fixed the way the master resets the file size limit
+       to avoid problems when a Postfix daemon updates a queue
+       file.  The file size limit is now increased to INT_MAX if
+       it is smaller than INT_MAX, so that it is less likely to
+       interfere than the old setting of message_size_limit.
+
+       Feature: disable mailbox size limits for the local and
+       virtual delivery agents by setting mailbox_size_limit or
+       virtual_mailbox_limit to zero.
+
+20010203
+
+       Cleanup: added one gruesome command to the postlink script
+       for hyperlinking nroff manual page output. Word abbreviation
+       broke some <a href...> </a> instances across line boundaries.
+       sed(1) is an amazing tool.  File: mantools/postlink.
+
+20010204
+
+       Laid the ground work for logging of table accesses. This
+       will give more insight into how Postfix uses its lookup
+       tables. User interface comes later.  File:  util/dict_debug.c.
+
+20010216
+
+       Bugfix: the pipe delivery agent expanded $size as if it
+       were a recipient, instead of expanding it as $nexthop or
+       as $sender. Reported by Michael Tokarev. File: pipe/pipe.c.
+
+20010221
+
+       Bugfix: poor LMTP performance for domains that are listed
+       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 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
+       sane_whatever workarounds. Reported by Andrew McNamara.
+       File: util/sane_socketpair.[hc]
+
+20010222
+
+       Documentation: the default main.cf file has a prominent
+       warning that mynetworks should be properly configured in
+       order to reject unauthorized mail relay requests from
+       strangers.
+
+       Documentation: the INSTALL document, section "mandatory
+       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 local 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.
+
+       INCOMPATIBLE CHANGE: POSTFIX NO LONGER RELAYS MAIL FOR
+       CLIENTS IN THE ENTIRE CLASS A/B/C NETWORK. POSTFIX BY
+       DEFAULT RELAYS MAIL FOR CLIENTS IN THE LOCAL SUBNETWORK.
+       Specify "mynetworks_style = class" to get the old behavior.
+
+20010225
+
+       Portability: master sigchld handler based on writing to a
+       pipe, so that the master wakes up from select(). Based on
+       code by Erik Forsberg, Linkoping University, Sweden.  File:
+       master/master_sig.c. Disabled until after the major release.
+
+       Code cleanup: Postfix should now run with no alias database.
+
+       Code cleanup: local_destination_recipient_limit and
+       local_destination_concurrency_limit have become first-class
+       configuration parameters. Files: global/mail_params.h,
+       *qmgr/qmgr.c, postconf/postconf.c.
+
+20010226
+
+       Documentation suggestions by Lars Hecking and Richard
+       Huxton, Matthias Andree and many others.
+
+       Code cleanup: some queue/transport operations need to be
+       moved, after the code cleanup of the recipient/concurrency
+       limit handling. Patrik Rak.  Files: *qmgr/qmgr_message.c.
index 49cf95a8ac1c9fd38c25dd8ca0daa6bf2519beeb..20d58268c25c1507b7b6186b7c587c1acc3f1962 100644 (file)
@@ -66,12 +66,15 @@ If your system is supported, it is one of
     Linux RedHat 4.x
     Linux RedHat 5.x
     Linux RedHat 6.x
+    Linux RedHat 7.x
     Linux Slackware 3.5
     Linux Slackware 4.0
     Linux Slackware 7.0
     Linux SuSE 5.x
     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
@@ -83,7 +86,7 @@ If your system is supported, it is one of
     Rhapsody 5.x
     SunOS 4.1.x
     SunOS 5.4..5.8 (Solaris 2.4..8)
-    Ultrix 4.x
+    Ultrix 4.x (well, that was long ago)
 
 or something closely resemblant.
 
@@ -202,7 +205,8 @@ In order to install or upgrade Postfix:
 
 - Run the INSTALL.sh script as the super-user:
 
-    # sh INSTALL.sh
+    # make install              (interactive version, first time install)
+    # make install </dev/null   (non-interactive version, for upgrades)
 
   The INSTALL.sh script offers suggestions for pathnames that you
   can override, either by editing INSTALL.sh or by specifying your
@@ -351,9 +355,10 @@ You can use $parameter before it is given a value. The Postfix
 configuration language uses lazy evaluation, and does not look at
 a parameter value until it is needed at runtime.
 
-First of all, you must specify what domain will be appended to a
-local address. The "myorigin" parameter defaults to the local
-hostname, but that is probably OK only for very small sites.
+First of all, you must specify what domain will be appended to an
+unqualified address (i.e. an address without @domain.name). The
+"myorigin" parameter defaults to the local hostname, but that is
+probably OK only for very small sites.
 
 Some examples:
 
@@ -363,8 +368,8 @@ Some examples:
 In the first case, local mail goes out as user@$myhostname, in
 the second case the sender address is user@$mydomain.
 
-Next you need to specify what mail addresses are local to the
-Postfix system.
+Next you need to specify what mail addresses Postfix should deliver
+locally.
 
 Some examples:
 
@@ -376,6 +381,14 @@ The first example is appropriate for a workstation, the second is
 appropriate for the mailserver for an entire domain. The third
 example should be used when running on a virtual host interface.
 
+If your machine is on an open network then you must specify what
+client IP addresses are authorized to relay their mail through your
+machine.  The default setting includes all class A, B or C networks
+that the machine is attached to. Often, that gives relay permission
+to too many clients.  My own settings are:
+
+    mynetworks = 168.100.189.0/28, 127.0.0.0/8
+
 If you're behind a firewall, you should set up a relayhost.  If
 you can, specify the organizational domain name so that Postfix
 can use DNS lookups, and so that it can fall back to a secondary
@@ -403,10 +416,11 @@ and/or dial-up networks.
 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.
+forward mail to a real person. Postfix has a sample aliases file
+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
@@ -417,10 +431,13 @@ impenetrable, but every little bit helps.
 With the exception of the Postfix local delivery and `pipe' daemons,
 every Postfix daemon can run chrooted.
 
-By default, no Postfix daemon runs chrooted.  In order to enable
-chroot operation, edit the file /etc/postfix/master.cf.  It is
-highly recommended to chroot the daemons that talk to the network:
-the smtp and smtpd processes.
+Sites with high security requirements should consider to chroot
+all daemons that talk to the network:  the smtp and smtpd processes,
+and perhaps also the lmtp client.
+
+The default /etc/postfix/master.cf file specifies that no Postfix
+daemon runs chrooted.  In order to enable chroot operation, edit
+the file /etc/postfix/master.cf. Instructions are in the file.
 
 Note that a chrooted daemon resolves all filenames relative to the
 Postfix queue directory (/var/spool/postfix). For successful use
index df4f74351f1ccdec61bcd5a3dafb0c40ac3dd63a..1ad76e988fb9c234c512ca38ff2e7eb65a47f949 100644 (file)
@@ -6,6 +6,7 @@
 PATH=/bin:/usr/bin:/usr/sbin:/usr/etc:/sbin:/etc
 umask 022
 
+test -t 0 &&
 cat <<EOF
 
 Warning: this script replaces existing sendmail or Postfix programs.
@@ -124,6 +125,7 @@ fi
 
 # Find out the location of configuration files.
 
+test -t 0 &&
 for name in install_root tempdir config_directory
 do
     while :
@@ -168,6 +170,7 @@ test -f $CONFIG_DIRECTORY/install.cf && . $CONFIG_DIRECTORY/install.cf
 
 # Override default settings.
 
+test -t 0 &&
 for name in daemon_directory command_directory \
     queue_directory sendmail_path newaliases_path mailq_path mail_owner\
     setgid manpages
@@ -342,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 07660e03108f411cab3916c46985c7003c15db19..e185ad0e6a85187ff8186c32541b0f014e9836fd 100644 (file)
@@ -26,6 +26,14 @@ Postfix source tree should work:
     % make makefiles CCARGS="-I/usr/local/include -DHAS_LDAP" \
        AUXLIBS="-L/usr/local/lib -lldap -L/usr/local/lib -llber"
 
+On Solaris 2.x you may have to specify run-time link information,
+otherwise ld.so will not find some of the shared libraries:
+
+    % make tidy
+    % make makefiles CCARGS="-I/usr/local/include -DHAS_LDAP" \
+       AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lldap \
+               -L/usr/local/lib -R/usr/local/lib -llber"
+
 The 'make tidy' command is needed only if you have previously built
 Postfix without LDAP support.
 
@@ -86,11 +94,12 @@ parameter below, "server_host", would be defined in main.cf as
        substitute for the address Postfix is trying to resolve, e.g.
                ldapsource_query_filter = (&(mail=%s)(paid_up=true))
 
-    domain (No default; you must configure this.)
+    domain (Default is to ignore this.)
        This is a list of domain names, paths to files, or dictionaries.
-       If specified, only lookups ending in a domain on this list will
-       be searched. This can significantly reduce the query load on the 
-       LDAP server.
+       If specified, only lookups for the domains on this list will be
+       performed.  This means that the LDAP map won't get searched for
+       'user', nor will it get searched for any domain not listed.  This
+       can significantly reduce the query load on the LDAP server.
                ldapsource_domain = postfix.org, hash:/etc/postfix/searchdomains
 
     result_attribute (maildrop)
similarity index 74%
rename from postfix/BEWARE
rename to postfix/LINUX_README
index 1b0c41829bc0b51d25bc111af04306b6de24a0ef..35a22a7a4266cc5df40dee714cf2409bd0b9c4d5 100644 (file)
@@ -1,3 +1,9 @@
+LINUX PORTABILITY
+=================
+
+On RedHat Linux 7.0, you must install the db3-devel RPM before you
+can compile the Postfix source code.
+
 LINUX SYSLOGD PERFORMANCE
 =========================
 
index 1c44a13959479f188d095f237795c57c7e89b29e..e6320db861354bd61d388351e4dd469c83706015 100644 (file)
-[Based on information that was provided by Amous Gouaux]
+[This file still needs to be updated - some information is obsolete]
 
-Postfix LMTP support
-====================
+1 - Postfix LMTP support
+========================
 
 LMTP stands for Local Mail Transfer Protocol, and is detailed in
-RFC2033.  This protocol is used to communicate with the final
-delivery agent, which may be on the local host or a remote host.
+RFC2033.  Postfix uses this protocol to communicate with the final
+delivery agent, which may run on the local host or a remote host.
 
 This protocol opens up interesting possibilities: one Postfix front
-end system can drive multiple mailbox back end systems over LMTP.
-As the mail load increases you add Postfix front end systems and
-LMTP mailbox back end systems.  You can use LDAP or mysql to share
-the user database among the front end and back end systems.
+end machine can drive multiple mailbox back end machines over LMTP.
+As the mail load increases, you add more Postfix front end systems
+and more LMTP mailbox back end systems.  This is the model that I
+had in mind when I began drafting the design for Postfix - a scalable
+architecture that allows you to keep adding SMTP servers and mailbox
+servers painlessly.
+
+Such a distributed architecture needs glue to keep things together.
+You can use a networked database LDAP or mysql to share the user
+database among the front end and back end systems. Use a replicated
+database so that no machine becomes a single point of failure for
+the entire mail infrastructure.
 
 Postfix LMTP support is based on a modified version of the Postfix
 SMTP client. The initial version was by Philip A.  Prindeville of
 Mirapoint, Inc., USA. This code was modified further by Amos Gouaux
-of University of Texas at Dallas, Richardson, USA.  Wietse Venema
-reduced the code to its present shape.
+of University of Texas at Dallas, Richardson, USA, who also revised
+much of the documentation.  Wietse Venema reduced the code to its
+present shape.
 
 
-Overview
-========
+2 - Overview
+============
 
 Most of the examples in this document involve the CMU Cyrus IMAP/POP
 server, available from:
 
     http://asg.web.cmu.edu/cyrus/
 
-While certainly not the only application that could make use of LMTP,
-it tends to be the most discussed.  These examples are based on the
-forthcoming Cyrus 2.0.10, at least at the time of writing.  The 2.x
-branch of Cyrus places greater emphasis on LMTP delivery than the
-previous releases.  Those using older releases of Cyrus can find a
-discussion in the appendix of this document.
+While certainly not the only application that could make use of
+LMTP, it tends to be the most discussed.  These examples are based
+on the forthcoming Cyrus 2.0.10, at least at the time of writing.
+The 2.x branch of Cyrus places greater emphasis on LMTP delivery
+than the previous releases.  Those using older releases of Cyrus
+can find a discussion in the appendix of this document.
 
 There are a variety of ways LMTP delivery can be configured in
-Postfix.  The two basic flavors are delivery over UNIX-domain sockets
-and delivery over TCP sockets.  Both flavors can be specified in
-either the Postfix main.cf or in a transport map.  The best approach
-to use depends upon the arrangement of your servers and the desired
-level of parallelization.  Please be sure to study this entire
-document as there are trade-offs in convenience and performance with
-these different approaches.
-
-The precise syntax for UNIX-domain and TCP connection endpoints is
-given in the lmtp(8) manual page.
+Postfix.  The two basic flavors are delivery over UNIX-domain
+sockets and delivery over TCP sockets.
 
+  o Connections over UNIX-domain sockets limit delivery to LMTP
+    servers running on the same machine.
 
-Using main.cf configuration
-===========================
+  o Connections over TCP sockets allow you to deliver to LMTP
+    servers across a local network.
 
-This is the simplest LMTP configuration.  The settings
-local_transport, mailbox_transport, and fallback_transport can
-support the following connections:
-
-1.  LMTP over TCP sockets.
+The precise syntax for UNIX-domain and TCP connection endpoints is
+given in the lmtp(8) manual page. Examples are also given in the
+text below.
 
-    mailbox_transport = lmtp
+Both socket flavors can be specified in either the Postfix main.cf
+file (see section 5) or in a Postfix transport map (section 6).
+What is the best approach for you depends upon the arrangement of
+your servers and the desired level of parallelization.
 
-    Instead of delivering local mail to a mail box such as
-    /var/mail/$user, a connection will be made over TCP to an LMTP
-    server.  Currently the default port for this connection is 24,
-    but this can be customized in the "/etc/services" file.
+Please be sure to study this entire document as there are trade-offs
+in convenience and in performance with these different approaches.
 
-    NOTE:
+3 - LMTP over UNIX-domain sockets
+=================================
 
-        With connections over TCP sockets, some Cyrus implementations
-        insist on SASL-style authentication, which is not currently
-        supported by the Postfix LMTP client.  See the examples below 
-        for additional details.
+A UNIX-domain socket is specified as the socket type ("unix") and
+a name in the local file system:
 
+    unix:/path/name
 
-2.  LMTP over UNIX-domain sockets.
+The "/path/name" part should be the name of a socket created by
+the LMTP server on the local machine. See the specific examples
+later in this document.
 
-    mailbox_transport = lmtp:unix:/path/name
+NOTE:
 
-    In this case the LMTP connection will be made over a UNIX-domain
-    socket.  This "/path/name" should be the socket created by the
-    LMTP server on the local machine.
+    If you run the lmtp client chrooted, the interpretation of the
+    /path/name is relative to the Postfix queue directory (typically,
+    /var/spool/postfix).
 
-    NOTE 1:
+    By default, the Postfix LMTP client does not run chrooted.
+    With LMTP delivery to the local machine there is no good reason
+    to run the Postfix LMTP client chrooted.
 
-        If you configured Cyrus using the "--with-libwrap" option, be 
-        sure to allow access to the "lmtpd" service from "0.0.0.0".
-        Otherwise LMTP deliveries over UNIX-domain sockets will be
-        blocked.  See the examples below for more on using libwrap.
+4 - LMTP over TCP sockets
+=========================
 
-    NOTE 2:
+A TCP destination is specified as the socket type ("inet"), the
+destination hostname and the TCP port:
 
-       If you run the lmtp client chrooted, the interpretation of
-       the /path/name is relative to the Postfix queue directory
-       (typically, /var/spool/postfix).
+    inet:hostname:port
 
-    NOTE 3:
+The "inet:" part can be omitted, as it is the default socket type.
 
-       By default, the Postfix LMTP client does not run chrooted.
-       With LMTP delivery to the local machine there is no good
-       reason to run the Postfix LMTP client chrooted.
+The destination port can be omitted as well. Currently the default
+TCP port number for this type of connection is 24, but this can be
+customized in the "/etc/services" file.  Specific examples are
+given later in this document.
 
+NOTE:
 
-Examples:
+    With connections over TCP sockets, later Cyrus LMTP server
+    implementations insist on SASL-style authentication. This means
+    that Postfix must be built with SASL support (see SASL_README).
+    The examples below show how to enable this in the Postfix LMTP
+    client.
 
-1.  LMTP over UNIX-domain sockets.
+    Some Cyrus LMTP server implementations do not allow SASL-style
+    authentication via plaintext passwords. You will have to jump
+    some extra hoops in order to enable MD5 password support, or
+    you will have to wait until this restriction is relaxed.
 
-    To utilize UNIX-domain sockets for the communication between
-    Postfix and Cyrus, the corresponding configuration files should
-    look something like this:
 
-    /etc/cyrus.conf:
+5 - Configuring LMTP using main.cf configuration
+================================================
 
-        SERVICES { 
-            ... 
-            lmtpunix cmd="lmtpd" listen="/var/imap/socket/lmtp" prefork=1
-            ... 
-        } 
-
-    /etc/postfix/main.cf:
+This is the simplest LMTP configuration.  
 
-        mailbox_transport = lmtp:unix:/var/imap/socket/lmtp
+5.1 - Delivery mechanisms
+-------------------------
 
-    In this case, mail that is resolved to be local will be delivered
-    to the Cyrus lmtpd server via the socket "/var/imap/socket/lmtp".  
+Postfix main.cf supports three mechanisms to deliver mail over
+LMTP.  Each method can use UNIX-domain or TCP sockets as described
+in a later section.
 
-    If you configured Cyrus using the "--with-libwrap" option, you
-    will need the following:
-
-    /etc/hosts.allow:
-
-        lmtpd : 0.0.0.0
-
-2.  LMTP over TCP sockets.
-
-    For this example, suppose the following files are configured
-    thusly: 
-
-    /etc/cyrus.conf:
-
-        SERVICES { 
-            ... 
-            lmtp cmd="lmtpd -a" listen="127.0.0.1:lmtp" prefork=0 
-            ... 
-        } 
+main.cf mechanism 1
+-------------------
 
-XXX does this mean that connections will be accepted only on 127.0.0.1?
+mailbox_transport = lmtp:unix:/path/name (UNIX-domain socket example)
+mailbox_transport = lmtp:hostname:port   (TCP socket example)
 
-    /etc/services:
+Mail that resolves as local (domain is listed in $mydestination)
+is given to the Postfix local delivery agent.  The Postfix local
+delivery agent expands aliases and .forward files, and delegates
+mailbox delivery to the LMTP server.
 
-        lmtp 2003/tcp
+main.cf mechanism 2
+-------------------
 
-    /etc/postfix/main.cf:
+local_transport = lmtp:unix:/path/name (UNIX-domain socket example)
+local_transport = lmtp:hostname:port   (TCP socket example)
 
-        mailbox_transport = lmtp
+Mail that resolves as local (domain is listed in $mydestination)
+is directly given to the LMTP server.  The mail is not processed
+by the Postfix local delivery agent; therefore aliases and .forward
+files are not processed.
 
-    /etc/postfix/master.cf:
+main.cf mechanism 3
+-------------------
 
-        lmtp      unix  -       -       n       -       -       lmtp
+fallback_transport = lmtp:unix:/path/name (UNIX-domain socket example)
+fallback_transport = lmtp:hostname:port   (TCP socket example)
 
-    Mail that Postfix resolves to be local will be delivered via TCP
-    to the Cyrus LMTP server.  Postfix will make a connection to port
-    2003 on the local host, subsequently transmitting the message to
-    the lmtpd server managed by the Cyrus master process.  Since
-    Postfix does not currently support LMTP-AUTH, the "-a" lmtpd
-    option is required.
+Mail that resolves as local (domain is listed in $mydestination)
+is given to the Postfix local delivery agent.  The Postfix local
+delivery agent processes aliases and .forward files, and delivers
+to /var[/spool]/mail/$user for users that have a UNIX account.
+Mail for other local users is delegated to the LMTP server.
 
-    CAUTION:
+5.2 - Examples
+--------------
 
-        If you run lmtpd with the "-a" option, be certain that you
-        restrict what systems can connect to this service.  This can
-        be done in either one of two ways:
+5.2.1 - LMTP over UNIX-domain sockets
+-------------------------------------
 
-        a.  Compile Cyrus with libwrap support, configuring
-            "/etc/hosts.allow" to restrict access to this service to
-            only your mail server.
+To utilize UNIX-domain sockets for the communication between
+Postfix and Cyrus, the corresponding configuration files should
+look something like this:
 
-        b.  In the cyrus.conf file, for the "listen" argument to the
-            "lmtp" service, specify the address (in this case
-            localhost), that the service should bind to.  This can
-            also be convenient if you have a private network between
-            your Postfix server and your Cyrus server.
+/etc/cyrus.conf:
 
-        If neither of these actions are taken, anybody will be able
-        to drop junk into your Cyrus message store!  
+    SERVICES { 
+       ... 
+       lmtpunix cmd="lmtpd" listen="/var/imap/socket/lmtp" prefork=1
+       ... 
+    } 
 
+/etc/postfix/main.cf:
 
-3.  LMTP over TCP sockets, using hosts.allow.
+    mailbox_transport = lmtp:unix:/var/imap/socket/lmtp
 
-    While similar to the previous example, this one varies in how the
-    lmtpd service is protected from unauthorized use.  Instead of
-    binding the lmtpd service to a specific Internet address, access
-    will be controlled using the "/etc/hosts.allow" tcp_wrappers
-    configuration file.  The tcp_wrappers package is available from:
+In this case, the Postfix local delivery agent expands aliases
+and .forward files, and delegates mailbox delivery to the Cyrus
+lmtpd server via the socket "/var/imap/socket/lmtp".
 
-        ftp://ftp.porcupine.org/pub/security/index.html
+5.2.2 - LMTP over TCP sockets
+-----------------------------
 
-    To take advantage of tcp_wrappers, Cyrus will need to be
-    configured using the "--with-libwrap" option.  See the Cyrus
-    documentation for more details.
+For this example, suppose the following files are configured
+thusly: 
 
-    Here are excerpts of the pertinent files:
+/etc/cyrus.conf:
 
-    /etc/hosts.allow:
+    SERVICES { 
+       ... 
+       lmtp cmd="lmtpd" listen="127.0.0.1:lmtp" prefork=0 
+       ... 
+    } 
 
-        lmtpd : localhost : ALLOW
-        lmtpd : ALL@ALL : DENY
+/etc/services:
 
-    /etc/cyrus.conf:
+    lmtp 24/tcp
 
-        SERVICES { 
-            ... 
-            lmtp cmd="lmtpd -a" listen="lmtp" prefork=0 
-            ... 
-        } 
+/etc/postfix/main.cf:
 
-    /etc/services:
+    mailbox_transport = lmtp:localhost
+    lmtp_sasl_auth_enable = yes
+    lmtp_sasl_password_maps = hash:/etc/postfix/lmtp_sasl_pass
 
-        lmtp 2003/tcp
+/etc/postfix/master.cf:
 
-    /etc/postfix/main.cf:
+    lmtp      unix  -       -       n       -       -       lmtp
 
-        mailbox_transport = lmtp
+/etc/postfix/lmtp_sasl_pass:
+    localhost.my.domain        username:password
 
-    The syntax shown in the hosts.allow excerpt above is valid if
-    tcp_wrappers is compiled using a "make" argument of:
+Instead of "hash", use the map type of your choice.  Some systems
+use "dbm" instead.  Use "postconf -m" to find out what map types
+are supported.
 
-        STYLE=-DPROCESS_OPTIONS
+With the above settings, the Postfix local delivery agent expands
+aliases and .forward files, and delegates mailbox delivery to the
+the Cyrus LMTP server.  Postfix makes a connection to port 24 on
+the local host, subsequently transmitting the message to the lmtpd
+server managed by the Cyrus master process.
 
-    See the tcp_wrappers hosts_options(5) man page for more details.
 
+6 - Configuring LMTP using transport map configuration
+======================================================
 
-Using transport map configuration
-=================================
+This approach is quite similar to specifying the LMTP service in
+the Postfix main.cf configuration file.  However, now we will use
+a transport map to route mail to the appropriate LMTP server,
+instead of depending on delegation by the Postfix local delivery
+agent.
 
-This approach is quite similar to specifying the LMTP service in the
-Postfix main.cf configuration file.  However, now we will use a
-transport map to route mail to the appropriate LMTP server.  Why
-might this approach be useful?  This could be handy if you wish to
-route mail for multiple domains to their respective mail retrieval
+Why might this approach be useful?  This could be handy if you wish
+to route mail for multiple domains to their respective mail retrieval
 (IMAP/POP) server.  Example:
 
     /etc/postfix/transport:
@@ -253,51 +258,55 @@ route mail for multiple domains to their respective mail retrieval
 
         transport_maps = hash:/etc/postfix/transport
 
+For details of the Cyrus LMTP server configuration, see section 5.
+
 Instead of "hash", use the map type of your choice.  Some systems use
 "dbm" instead.  Use "postconf -m" to find out what map types are
 supported.
 
 
-Performance considerations
-==========================
+7 - Performance considerations
+==============================
 
 Hopefully the preceding discussion has seemed pretty straight
 forward.  Now things get interesting.  After reading the following
-you will see that there are more factors to consider when setting up
-LMTP services.
+you will see that there are more factors to consider when setting
+up LMTP services.
 
 
-Single instance message store
-=============================
+8 - Single instance message store
+=================================
 
 Presently this topic is more pertinent to sites running Cyrus, but
 may be a factor with other applications as well.
 
 Since 1.6.22, Cyrus has had the feature that if a message containing
-multiple recipients is received via the LMTP protocol, and all these
-recipients were on the same Cyrus partition, only one instance of
-this message would be written to the file system.  The other
+multiple recipients is received via the LMTP protocol, and all
+these recipients were on the same Cyrus partition, only one instance
+of this message would be written to the file system.  The other
 recipients would then see a hard link of this single instance.
-Depending on your user base, this can be considerable motivation to
-using LMTP. 
-
-However, there is a catch: currently the Postfix local delivery
-mechanisms are only designed to handle one recipient at a time, which
-in most cases is more than adequate.  So, if you wish to support
-single instance message store delivery, you will have to use a
-transport table to map these users to the appropriate LMTP
-destination.
-
-While the simplest thing to do would be to list the entire domain in
-the transport map for LMTP delivery, this by-passes alias expansion
-for otherwise local addresses.  If the site is to run software via
-aliases, like most Mailing List Management (MLM) software, a more
-complex solution is required.  Fortunately, a virtual table should do
-the trick.
+Depending on your user base, this can be considerable motivation
+to using LMTP.
+
+However, there is a catch: the Postfix local delivery agent is
+designed to deliver one recipient at a time, which in most cases
+is more than adequate.  So, if you wish to support single instance
+message store delivery, you will have to use a virtual table to
+map these users to the appropriate LMTP destination (at the time
+of writing, the Postfix transport table supports only per-domain
+routing, and not per-recipient routing).
+
+While the simplest thing to do would be to list the entire domain
+in the transport map for LMTP delivery, this by-passes alias
+expansion for otherwise local addresses (see section 5.1, delivery
+mechanism 2).  If the site is to run software via aliases, like
+most Mailing List Management (MLM) software, a more complex solution
+is required.  A virtual table should do the trick.
 
 As an example, suppose we wanted to support single instance message
-store delivery for the domain "example.org".  The configuration files
-for this domain could look something like this:
+store delivery for the hosted (not local) domain "example.org".
+The configuration files for this domain could look something like
+this:
 
     /etc/postfix/virtual:
 
@@ -334,21 +343,22 @@ for this domain could look something like this:
 Breaking things down, we begin with the address "mlist@example.org",
 which represents a mailing list.  By placing an entry in the virtual
 map to direct this mail to "mlist@localhost", we can override the
-transport map that would by default route all "@example.org" mail to
-a LMTP server via a UNIX-domain socket.
+transport map that would by default route all "@example.org" mail
+to a LMTP server via a UNIX-domain socket.
 
-To summarize, all mail that is to be processed by an alias entry must 
-first be diverted with a virtual table entry so that it does not fall 
-into the more general routing established by the transport table.
+To summarize, all mail that is to be processed by an alias entry
+must first be diverted with a virtual table entry so that it does
+not fall into the more general routing established by the transport
+table.
 
 
-Improving connection caching performance
-========================================
+9 - Improving connection caching performance
+============================================
 
 After delivering a message via LMTP, Postfix will keep the connection
 open for a while, so that it can be reused for a subsequent delivery.
 This reduces overhead of LMTP servers that create one process per
-connection.  
+connection.
 
 For LMTP connection caching to work, the Postfix LMTP client should
 not switch destination hosts.  This is no problem when you run only
@@ -356,7 +366,7 @@ one LMTP server. However, if you run multiple LMTP servers, this
 can be an issue.
 
 You can prevent the LMTP client from switching between servers by
-configuring a separate mail delivery transport for each LMTP server:
+configuring a separate LMTP delivery transport for each LMTP server:
 
     /etc/postfix/master.cf:
 
@@ -374,8 +384,8 @@ mail lmtp2 transport for the LMTP server #2, and so on.
         bar.com lmtp2:lmtp2host
 
 
-Appendix: Older Cyrus versions
-==============================
+10 - Appendix: Older Cyrus versions
+===================================
 
 First of all, if you are using a Cyrus 2.x version prior to 2.0.10,
 it would be good to upgrade.  The previous 2.x releases were beta
@@ -399,7 +409,7 @@ configure inetd.  This involves the following file edits:
 
     /etc/services:
 
-        lmtp 2003/tcp
+        lmtp 24/tcp
 
     /etc/inetd.conf:
 
@@ -454,14 +464,3 @@ you will notice the one significant difference with the Postfix
 configuration is the lack of mention of the UNIX-domain sockets.
 That is because delivery over UNIX-domain sockets is new with Cyrus
 2.x, yet another reason to upgrade.  :-)
-
-
-
-# Local Variables:
-# mode: text
-# mode: flyspell
-# fill-column: 69
-# End:
-
-
-
diff --git a/postfix/LMTP_README.old b/postfix/LMTP_README.old
deleted file mode 100644 (file)
index 873c6c3..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-BEGIN WARNING
-=============
-
-The information in this file is outdated. The Postfix LMTP server
-can now make connections over UNIX-domain sockets. 
-
-With connections over TCP sockets, some Cyrus implementations insist
-on SASL-style authentication, which is not supported by the Postfix
-LMTP client. In that case, use UNIX-domain sockets instead.
-
-The precise syntax for UNIX-domain and TCP connection endpoints is
-given in the lmtp(8) manual page.
-
-Examples:
-
-    /etc/postfix/transport:
-       domain1.name            lmtp1:unix:/path/name
-       domain2.name            lmtp2:lmtp2host
-
-    /etc/postfix/master.cf:
-        lmtp1      unix  -       -       n       -       -       lmtp
-        lmtp2      unix  -       -       n       -       -       lmtp
-
-The first example (domain1) uses UNIX-domain connections, the second
-example (domain2) uses TCP. 
-
-For optimal use of connection caching, specify separate mail delivery
-transports for each domain that receives mail via LMTP:
-
-END WARNING
-===========
-
-Postfix LMTP support
-====================
-
-Postfix LMTP support is based on a modified version of the Postfix
-SMTP client. The initial version was by Philip A.  Prindeville of
-Mirapoint, Inc., USA. This code was modified further by Amos Gouaux
-of University of Texas at Dallas, Richardson, USA.  Wietse Venema
-reduced the code to its present shape.
-
-Postfix can be configured to talk to a local or remote LMTP server.
-Most people will run the LMTP server on the same machine that runs
-Postfix. However, a remote LMTP server can be useful if Postfix
-runs on mail relay server(s) that feed incoming mail directly to
-the appropriate mailbox server(s). This way, mailbox servers do
-not need to run an SMTP server at all.  Tidy all the way around.
-
-Configuring the mailbox server (local or remote)
-================================================
-
-On the mailbox server, in this case a CMU Cyrus imapd/popd server,
-add the following to /etc/services:
-
-    pop3            110/tcp                         # Cyrus POP3
-    imap            143/tcp                         # Cyrus IMAP4
-    lmtp            24/tcp
-
-Next, put the following in /etc/inetd.conf:
-
-    lmtp    stream  tcp     nowait  cyrus   /usr/sbin/tcpd  /usr/local/cyrus/bin/deliver -e -l
-
-/usr/sbin/tcpd is from the tcp_wrappers package.  You want this to
-make sure only your mail relay(s) can talk to the LMTP server.
-Postfix by default does multiple deliveries per LMTP session
-(connection caching), so do not worry about the overhead of
-tcp_wrapping the LMTP port.
-
-On some systems, tcpd is built into inetd, so you do not have to
-specify tcpd in the inetd.conf file. Instead of tcpd/inetd, xinetd
-can do a similar job of logging and access control.
-
-Configuring Postfix
-===================
-
-Similar changes to /etc/services:
-
-    lmtp            24/tcp
-
-You may have to add the following entry to /etc/postfix/master.cf:
-
-    lmtp      unix  -       -       n       -       -       lmtp
-
-NOTE:  Root privileges are not necessary!
-
-Put this in /etc/postfix/transport:
-
-    inbox.domain.org     lmtp:inbox.domain.org
-
-Naturally, this means we also need in /etc/postfix/main.cf:
-
-    transport_maps      = hash:/etc/postfix/transport
-
-Instead of "hash", use the map type of your choice. Some systems
-use "dbm" instead. Use "postconf -m" to find out what map types
-are supported.
-
-Improving connection caching performance
-========================================
-
-After delivering a message via LMTP, Postfix will keep the connection
-open for a while, so that it can be reused for a subsequent delivery.
-This reduces overhead of LMTP servers that create one process per
-connection.  
-
-For LMTP connection caching to work, the Postfix LMTP client should
-not switch destination hosts.  This is no problem when you run only
-one LMTP server. However, if you run multiple LMTP servers, this
-can be an issue.
-
-You can prevent the LMTP client from switching between servers by
-configuring a separate mail delivery transport for each LMTP server:
-
-    /etc/postfix/master.cf:
-        lmtp1      unix  -       -       n       -       -       lmtp
-        lmtp2      unix  -       -       n       -       -       lmtp
-          .         .    .       .       .       .       .        .
-
-Configure transport table entries such that the lmtp1 mail delivery
-transport is used for all deliveries to the LMTP server #1, the
-mail lmtp2 transport for the LMTP server #2, and so on.
-
-    /etc/postfix/transport:
-        foo.com lmtp1:lmtp1host
-        bar.com lmtp2:lmtp2host
index d3b4fc9fa0a0ad295d219510dc1a6bcc46489252..6f97edcfa599f618d1858c3bc97d9fc3d26f8bb0 100644 (file)
@@ -19,8 +19,8 @@ from:
 You will need to add -DHAS_PCRE and a -I for the PCRE header to CCARGS,
 and add the path to the PCRE library to AUXLIBS, for example:
 
-   make -f Makefile.init makefiles 'CCARGS=-DHAS_PCRE -I../../pcre-2.08' \
-      'AUXLIBS=../../pcre-2.08/libpcre.a'
+   make -f Makefile.init makefiles 'CCARGS=-DHAS_PCRE -I../../../pcre-2.08' \
+      'AUXLIBS=../../../pcre-2.08/libpcre.a'
 
 [note: pcre versions before 2.06 are no longer compatible -- Wietse]
 
index af3e6c7bfc4a93b798d039958e3952f0d322bef9..9fcf519b35b8b5e255d5680beb8f425ec6d55350 100644 (file)
-REJECT by header/body_checks are now flagged as policy violations
-rather than bounces, for consistency in postmaster notifications.
+This is the first official Postfix release that is not called BETA.
+May it help the people who cannot get BETA software past their
+management.
 
-Major changes with snapshot-20001217
-====================================
+Release 20010228 differs from snapshot 20010228 in that the virtual
+delivery agent and nqmgr queue manager are left out. That software
+will become part of the official release when it has not changed
+in a while.
 
-This release involves little change in functionality and a lot of
-small changes to lots of files. The code is put out as a separate
-snapshot release so that I have a tested baseline for further work.
+In the text below, incompatible changes are labeled with the Postfix
+version that introduced the change. If you upgrade from a later
+Postfix version, then you do not have to worry about that particular
+incompatibility.
 
-All time-related configuration parameters now accept a one-letter
-suffix to indicate the time unit (s: second, m: minute, h: hour,
-d: day, w: week). The exceptions are the LDAP and MYSQL modules
-which are maintained separately.
+Major incompatible changes with release-20010228
+================================================
 
-The mysql client was partially rewritten in order to elimimate some
-memory allocation/deallocation problems. The code needs more work,
-and needs to be tested in a real production environment.
+[snapshot-20010225] POSTFIX NO LONGER RELAYS MAIL FOR CLIENTS IN
+THE ENTIRE CLASS A/B/C NETWORK. To get the old behavior, specify
+"mynetworks_style = class" in the main.cf file. The default
+(mynetworks_style = subnet) is to relay for clients in the local
+IP subnet. See conf/main.cf.
 
-The local_transport and default_transport configuration parameters
-can now be specified in transport:destination notation, just like
-the mailbox_transport and fallback_transport parameters.  The
-:destination part is optional.  However, these parameters take only
-one destination, unlike relayhost and fallback-relay which take
-any number of destinations.
+[snapshot-20001005, snapshot-20010225] You must execute "postfix
+stop" before installing this release.  Some recommended parameter
+settings have changed, and a new entry must be added to the master.cf
+file before you can start Postfix again.
 
-Incompatible changes with snapshot-20001210
-===========================================
+1 - The recommended Postfix configuration no longer uses flat
+    directories for the "incoming" "active", "bounce", and "defer"
+    queue directories.  The "flush" directory for the new "flush"
+    service directory should not be flat either.
 
-If this release does not work for you, you can go back to a previous
-Postfix version without losing your mail, subject to the "incompatible
-changes" listed for previous Postfix releases below.
-
-When delivering to /file/name (as directed in an alias or .forward
-file), the local delivery agent now logs a warning when it is unable
-to create a /file/name.lock file. Mail is still delivered as before.
-
-The "sun_mailtool_compatibility" feature is going away (a compatibility
-mode that turns off kernel locks on mailbox files). It still works,
-but a warning is logged. Instead of using "sun_mailtool_compatibility",
-specify the mailbox locking strategy as "mailbox_delivery_lock =
-dotlock".
-
-The Postfix SMTP client now skips SMTP server replies that do not
-start with "CODE SPACE" or with "CODE HYPHEN" and flags them as
-protocol errors. Older Postfix SMTP clients silently treated "CODE
-TEXT" as "CODE SPACE TEXT", i.e. as a valid SMTP reply.
-
-This snapshot does not yet change default relay settings. That
-change alone affects a dozen files, most of which documentation.
-This may be an incompatibility with some people's expectations,
-but such are my rules - between code freeze and release no major
-functionality changes are allowed.
-
-Several interfaces of libutil and libglobal routines have changed.
-This may break third-party code written for Postfix. In particular,
-the safe_open() routine has changed, the way the preferred locking
-method is specified in the sys_defs.h file, as well as all routines
-that perform file locking. When compiling third-party code written
-for Postfix, the incompatibilities will be detected by the compiler
-provided that #include file dependencies are properly maintained.
-
-Major changes with snapshot-20001210
-====================================
+    Upon start-up, Postfix checks if the hash_queue_names configuration
+    parameter is properly set up, and will add any queue directory
+    names that are missing.
+
+2 - In order to improve performance of one-to-one mail deliveries
+    the queue manager will now look at up to 10000 queue files
+    (was: 1000).  The default qmgr_message_active_limit setting
+    was changed accordingly.
+
+    If you have a non-default qmgr_message_active_limit in main.cf,
+    you may want adjust it.
+
+3 - The new "flush" service needs to be configured in master.cf.
+
+    Upon start-up, Postfix checks if the new "flush" service is
+    configured in the master.cf file, and will add an entry if it
+    is missing.
+
+Should you wish to back out to a previous Postfix release there is
+no need to undo the above queue configuration changes.
+
+[snapshot-20000921] The protocol between queue manager and delivery
+agents has changed.  This means that you cannot mix the Postfix
+queue manager or delivery agents with those of Postfix versions
+prior to 20000921. This change does not affect Postfix queue file
+formats.
+
+[snapshot-20000529] This release introduces an incompatible queue
+file format change ONLY when content filtering is enabled (see text
+in FILTER_README). Old Postfix queue files will work fine, but
+queue files with the new content filtering info will not work with
+Postfix versions before 20000529.  Postfix logs a warning and moves
+incompatible queue files to the "corrupt" mail queue subdirectory.
+
+Minor incompatible changes with release-20010228
+================================================
+
+[snapshot-20010225] The incoming and deferred queue directories
+are now hashed by default.  This improves the performance considerably
+under heavy load, at the cost of a small but noticeable slowdown
+when one runs "mailq" on an unloaded system.
+
+[snapshot-20010222] 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, 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,
+where xxx is the name of the delivery mechanism).  This parameter
+controls the number of recipients that can be sent in one delivery
+(surprise).
+
+The setting of the per-transport recipient limit also controls the
+meaning of the per-transport destination concurrency limit (named
+xxx_destination_concurrency_limit, where xxx is again the name of
+the delivery mechanism):
+
+ 1) When the per-transport recipient limit is 1 (i.e., send one
+    recipient per delivery), the per-transport destination concurrency
+    limit controls the number of simultaneous deliveries to the
+    same recipient.  This is the default behavior for delivery via
+    the Postfix local delivery agent.
+
+ 2) When the per-transport recipient limit is > 1 (i.e., send
+    multiple recipients per delivery), the per-transport destination
+    concurrency limit controls the number of simultaneous deliveries
+    to the same domain.  This is the default behavior for all other
+    Postfix delivery agents.
+
+[snapshot-20010128] The Postfix local delivery agent now enforces
+mailbox file size limits (default: mailbox_size_limit = 51200000).
+This limit affects all file write access by the local delivery
+agent or by a process run by the local delivery agent. The purpose
+of this parameter is to act as a safety for run-away software. It
+cannot be a substitute for a file quota management system. Specify
+a limit of 0 to disable.
+
+[snapshot-20010128] REJECT in header/body_checks is now flagged as
+policy violation rather than bounce, for consistency in postmaster
+notifications.
+
+[snapshot-20010128] The default RBL (real-time blackhole lists)
+domain examples have been changed from *.vix.com to *.mail-abuse.org.
+
+[snapshot-20001210] Several interfaces of libutil and libglobal
+routines have changed.  This may break third-party code written
+for Postfix. In particular, the safe_open() routine has changed,
+the way the preferred locking method is specified in the sys_defs.h
+file, as well as all routines that perform file locking. When
+compiling third-party code written for Postfix, the incompatibilities
+will be detected by the compiler provided that #include file
+dependencies are properly maintained.
+
+[snapshot-20001210] When delivering to /file/name (as directed in
+an alias or .forward file), the local delivery agent now logs a
+warning when it is unable to create a /file/name.lock file. Mail
+is still delivered as before.
+
+[snapshot-20001210] The "sun_mailtool_compatibility" feature is
+going away (a compatibility mode that turns off kernel locks on
+mailbox files). It still works, but a warning is logged. Instead
+of using "sun_mailtool_compatibility", specify the mailbox locking
+strategy as "mailbox_delivery_lock = dotlock".
+
+[snapshot-20001210] The Postfix SMTP client now skips SMTP server
+replies that do not start with "CODE SPACE" or with "CODE HYPHEN"
+and flags them as protocol errors. Older Postfix SMTP clients
+silently treated "CODE TEXT" as "CODE SPACE TEXT", i.e. as a valid
+SMTP reply.
+
+[snapshot-20001121] On RedHat Linux 7.0, you must install the
+db3-devel RPM before you can compile the Postfix source code.
+
+[snapshot-20000924] The postmaster address in the "sorry" text at
+the top of bounced mail is now just postmaster, not postmaster@machine.
+The idea is to refer users to their own postmaster.
+
+[snapshot-20000921] The notation of [host:port] in transport tables
+etc. is going away but it is still supported. The preferred form
+is now [host]:port.  This change is necessary to support IPV6
+address forms which use ":" as part of a numeric IP address. In a
+future release, Postfix will log a warning when it encounters the
+[host:port] form.
+
+[snapshot-20000921] In mail headers, Errors-To:, Reply-To: and
+Return-Receipt:  addresses are now rewritten as a sender address
+(was: recipient).
+
+[snapshot-20000921] Postfix no longer inserts Sender: message
+headers.
+
+[snapshot-20000921] The queue manager now logs the original number
+of recipients when opening a queue file (example: from=<>, size=3502,
+nrcpt=1).
+
+[snapshot-20000921] The local delivery agent no longer appends a
+blank line to mail that is delivered to external command.
+
+[snapshot-20000921] The pipe delivery agent no longer appends a
+blank line when the F flag is specified (in the master.cf file).
+Specify the B flag if you need that blank line.
+
+[snapshot-20000507] As required by RFC 822, Postfix now inserts a
+generic destination message header when no destination header is
+present.  The text is specified via the undisclosed_recipients_header
+configuration parameter (default:  "To: undisclosed-recipients:;").
+
+[snapshot-20000507] The Postfix sendmail command treats a line with
+only `.' as the end of input, for the sake of sendmail compatibility.
+To disable this feature, specify the sendmail-compatible `-i' or
+`-oi' flags on the sendmail command line.
+
+[snapshot-20000507] For the sake of Sendmail compatibility, the
+Postfix SMTP client skips over SMTP servers that greet with a 4XX
+or 5XX reply code, treating them as unreachable servers.  To obtain
+prior behavior (4XX=retry, 5XX=bounce), specify "smtp_skip_4xx_greeting
+= no" and "smtp_skip_5xx_greeting = no".
+
+Major changes with release-20010228
+===================================
+
+Postfix produces DSN formatted bounced/delayed mail notifications.
+The human-readable text still exists, so that users will not have
+to be unnecessarily confused by all the ugliness of RFC 1894.  Full
+DSN support will be later.
+
+This release introduces full content filtering through an external
+process. This involves an incompatible change in queue file format.
+Mail is delivered to content filtering software via an existing
+mail delivery agent, and is re-injected into Postfix via an existing
+mail submission agent.  See examples in the FILTER_README file.
+Depending on how the filter is implemented, you can expect to lose
+a factor of 2 to 4 in delivery performance of SMTP transit mail,
+more if the content filtering software needs lots of CPU or memory.
+
+Specify "body_checks = regexp:/etc/postfix/body_checks" for a quick
+and dirty emergency content filter that looks at non-header lines
+one line at a time (including MIME headers inside the message body).
+Details in conf/sample-filter.cf.
+
+The header_checks and body_checks features can be used to strip
+out unwanted data. Specify IGNORE on the right-hand side and the
+data will disappear from the mail.
 
-This snapshot includes bugfixes that were already released as
-patches 12 and 13 for the 19991231 "stable" release:
+Support for SASL (RFC 2554) authentication in the SMTP server and
+in the SMTP and LMTP clients. See the SASL_README file for more
+details. This file still needs better examples.
 
-  - The queue manager could deadlock for 10 seconds when bouncing
-    mail under extreme load from one-to-one mass mailings.
+Postfix now ships with an LMTP delivery agent that can deliver over
+local/remote TCP sockets and over local UNIX-domain sockets.  The
+LMTP_README file gives example, but still needs to be revised.
 
-  - Local delivery performance was substandard, because the per-user
-    concurrency limit accidentally applied to the entire local
-    domain.
+Fast "ETRN" and "sendmail -qR".  Postfix maintains per-destination
+logfiles with information about what mail is queued for selected
+destinations.  See the file ETRN_README for details.
 
 The mailbox locking style is now fully configurable at runtime.
 The new configuration parameter is called "mailbox_delivery_lock".
@@ -82,11 +238,14 @@ mailbox locking style is system dependent.  This change affects
 all mailbox and all "/file/name" deliveries by the Postfix local
 delivery agent.
 
-The new "import_environment" and "export_environment" configuration
-parameters now provide explicit control over what environment
-variables Postfix will import, and what environment variables
-Postfix will pass on to a non-Postfix process. This is better than
-hard-coding my debugging environment into public releases.
+Minor changes with release-20010228
+===================================
+
+You can now specify multiple SMTP destinations in the relayhost
+and fallback_relay configuration parameters. The destinations are
+tried in the specified order. Specify host or host:port (perform
+MX record lookups), [host] or [host]:port (no MX record lookups),
+[address] or [address]:port (numerical IP address).
 
 The "mailbox_transport" and "fallback_transport" parameters now
 understand the form "transport:nexthop", with suitable defaults
@@ -94,25 +253,12 @@ when either transport or nexthop are omitted, just like in the
 Postfix transport map. This allows you to specify for example,
 "mailbox_transport = lmtp:unix:/file/name".
 
-The MYSQL client now supports server connections over UNIX-domain
-sockets.  Code provided by Piotr Klaban. See the file MYSQL_README
-for examples of "host" syntax.
-
-Incompatible changes with snapshot-20001121
-===========================================
-
-If this release does not work for you, you can go back to a previous
-Postfix version without losing your mail, subject to the "incompatible
-changes" listed for previous Postfix releases below.
-
-Major changes with snapshot-20001121
-====================================
-
-Support for RedHat Linux 7.0.  On RedHat Linux 7.0, you must install
-the db3-devel RPM before you can compile the Postfix source code.
-
-The mailbox_transport feature works again. It was broken when the
-"require_home_directory" feature was added.
+The local_transport and default_transport configuration parameters
+can now be specified in transport:destination notation, just like
+the mailbox_transport and fallback_transport parameters.  The
+:destination part is optional.  However, these parameters take only
+one destination, unlike relayhost and fallback-relay which take
+any number of destinations.
 
 More general virtual domain support.  Postfix now supports both
 Sendmail-style virtual domains and Postfix-style virtual domains.
@@ -131,270 +277,43 @@ in main.cf to prevent the SMTP server from bouncing mail while you
 are testing configurations. Until this release the SMTP server was
 not aware of soft bounces.
 
-Incompatible changes with snapshot-20001029
-===========================================
-
-If this release does not work for you, you can go back to a previous
-Postfix version without losing your mail, subject to the "incompatible
-changes" listed for previous Postfix releases below.
-
-Berkeley DB support has changed for Solaris, HP-UX, UNIXWARE, IRIX.
-On these systems, Postfix must no longer use DB 1.85 compatibility
-mode, because that mode loses the file lock while building a table,
-so that table lookups fail and mail is lost. See the DB_README file
-for instructions on how to build Postfix with third-party Berkeley
-DB support.
-
-The "fast ETRN" policy configuration has changed. You now specify
-the list of eligible "fast ETRN" domains with the fast_flush_domains
-parameter (default: $relay_domains). In order to disable the feature,
-specify an empty value (fast_flush_domains =).
-
-Major changes with snapshot-20001029
-====================================
-
-This release ships with an updated LDAP client module that has better
-group support by Lamont Jones, and that has several other enhancements.
-Review the LDAP_README file for more information.
-
-The LMTP client can now make connections over UNIX-domain sockets
-in addition to IPV4.  For connections over UNIX-domain sockets,
-specify a transport table entry like:
-
-    domain.name                lmtp:unix:/path/name
-
-IPV4-based servers are still the default. The LMTP_README file
-still needs to be revised to account for this change. This is
-best done by someone who actually uses the Postfix LMTP client.
-
-You can now specify multiple SMTP destinations in the relayhost
-and fallback_relay configuration parameters. The destinations are
-tried in the specified order. Specify host or host:port (perform
-MX record lookups), [host] or [host]:port (no MX record lookups),
-[address] or [address]:port (numerical IP address).
-
-Incompatible changes with snapshot-20001005
-===========================================
-
-If this release does not work for you, you can go back to a previous
-Postfix version without losing your mail, subject to the "incompatible
-changes" listed for previous Postfix releases below.
-
-You must execute "postfix stop" before installing this release.
-Some recommended parameter settings have changed, and a new entry
-must be added to the master.cf file before you can start Postfix
-again.
-
-1 - The recommended Postfix configuration no longer uses flat
-    directories for the "active", "bounce", and "defer" queue
-    directories.  The "flush" directory for the new "flush" service
-    directory should not be flat either.
-
-    Upon start-up, Postfix checks if the hash_queue_names configuration
-    parameter is properly set up, and will add any queue directory
-    names that are missing.
-
-2 - In order to improve performance of one-to-one mail deliveries
-    the queue manager will now look at up to 10000 queue files
-    (was: 1000).  The default qmgr_message_active_limit setting
-    was changed accordingly.
-
-    If you have a non-default qmgr_message_active_limit in main.cf,
-    you may want adjust it.
-
-3 - The new "flush" service needs to be configured in master.cf.
+Workarounds for non-standard RFC 2554 (AUTH command) implementations.
+Specify "broken_sasl_auth_clients = yes" to enable SMTP server
+support for old Microsoft client applications. The Postfix SMTP
+client supports non-standard RFC 2554 servers by default.
 
-    Upon start-up, Postfix checks if the new "flush" service is
-    configured in the master.cf file, and will add an entry if it
-    is missing.
-
-Should you wish to back out to a previous Postfix release there is
-no need to undo the above changes.
+All time-related configuration parameters now accept a one-letter
+suffix to indicate the time unit (s: second, m: minute, h: hour,
+d: day, w: week). The exceptions are the LDAP and MYSQL modules
+which are maintained separately.
 
-Major changes with snapshot-20001005
-====================================
+New "import_environment" and "export_environment" configuration
+parameters provide explicit control over what environment variables
+Postfix will import, and what environment variables Postfix will
+pass on to a non-Postfix process.
 
 In order to improve performance of one-to-one deliveries, Postfix
 by default now looks at up to 10000 messages at a time (was: 1000).
 
-Until now, Postfix did a rather lame effort at implementing the
-SMTP ETRN command - it attempted to deliver all mail in the queue,
-regardless of its destination.  This is slow if your mail server
-queues mail for lots of different destinations.
-
-This release introduces fast "ETRN" and "sendmail -qR". These
-deliver only mail that is queued for the specified destination,
-without requiring Postfix to open every file in the mail queue.
-
-Postfix now maintains per-destination logfiles with information
-about what mail is queued for specific destinations.  By default,
-these logfiles are maintained only for destinations that Postfix
-is willing to relay to (as controlled by the relay_domains parameter).
-
-The maintenance policy for deferred mail logfiles is selected with
-the "fast_flush_policy" configuration parameter.  Possible values
-are:  "all" (maintain logs for all destinations), "relay" (maintain
-logs for relay destinations) or "none" (maintain no logs).
-
-Postfix falls back to the old slow ETRN for destinations that are
-not eligible for the fast "ETRN" and "sendmail -qR" service.
-
-See the file ETRN_README for details.
-
-Incompatible changes with snapshot-20000924
-===========================================
-
-The postmaster address in the "sorry" text at the top of bounced
-mail is now just postmaster, not postmaster@sending.machine.  The
-idea is to refer users to their own postmaster.
-
-Major changes with snapshot-20000924
-====================================
-
-DSN formatted bounced/delayed mail notifications, finally.  The
-human-readable text still exists, so that users will not have to
-be unnecessarily confused by all the ugliness of RFC 1894.
-
-Major changes with snapshot-20000923
-====================================
-
-The nqmgr (experimental smarter queue manager) has been updated.
-It no longer worked after the change in queue manager to delivery
-agent protocol.
-
 Specify "syslog_facility = log_local1" etc. to separate the logging
 from multiple Postfix instances. However, a non-default logging
 facility takes effect only after process initialization. Errors
 during command-line parsing are still logged with the default syslog
 facility, as are errors while processing the main.cf file.
 
-Incompatible changes with snapshot-20000921
-===========================================
-
-After "make install" you need to execute "postfix reload".  The
-protocol between queue manager and delivery agents has changed.
-This does not affect the format of existing queue files.  You just
-cannot mix this Postfix version's queue managers or delivery agents
-with older Postfix versions.
-
-The notation of [host:port] in transport tables etc. is going away
-but it is still supported. The preferred form is now [host]:port.
-This change is necessary to support IPV6 address forms which use
-":" as part of a numeric IP address. In a future release, Postfix
-will log a warning when it encounters the [host:port] form.
-
-In mail headers, Errors-To:, Reply-To: and Return-Receipt:  addresses
-are now rewritten as a sender address (was: recipient).
-
-Postfix no longer inserts Sender: message headers.
-
-The queue manager now logs the original number of recipients when
-opening a queue file (example: from=<>, size=3502, nrcpt=1).
-
-The local delivery agent no longer appends a blank line to mail
-that is delivered to external command.
-
-The pipe delivery agent no longer appends a blank line when the F
-flag is specified (in the master.cf file). Specify the B flag if
-you need that blank line.
-
-Major changes with snapshot-20000921
-====================================
-
 Postfix now strips out Content-Length: headers in incoming mail to
 avoid confusion in mail user agents.
 
-The header_checks and body_checks features can now be used to strip
-out unwanted data. Specify IGNORE and the data will disappear.
-
 Specify "require_home_directory = yes" to prevent mail from being
-delivered to a user whose home directory is not mounted.
+delivered to a user whose home directory is not mounted. This
+feature is implemented by the Postfix local delivery agent.
 
 The pipe mailer has a size limit (size=nnn) command-line argument.
 
-Incompatible changes with snapshot-20000531
-===========================================
-
-All references to "content inspection" have been replaced by "content
-filtering", in anticipation of hooks for true content inspection
-that does not re-inject mail back into Postfix.
-
-Incompatible changes with snapshot-20000529
-===========================================
-
-This version introduces an incompatible queue file format change
-when content filtering is enabled. Old Postfix queue files will
-work fine, but new queue files with content filtering info will
-not work with old Postfix versions. They log a warning and move
-incompatible queue files to the "corrupt" mail queue subdirectory.
-
-Major changes with snapshot-20000529
-====================================
-
-This version introduces full content filtering through an external
-process. This involves an incompatible change in queue file format.
-Mail is delivered to content filtering software via an existing
-mail delivery agent, and is re-injected into Postfix via an existing
-mail submission agent.  See examples in the FILTER_README file.
-Depending on how the filter is implemented, you can expect to lose
-a factor of 2 to 4 in delivery performance of SMTP transit mail,
-more if the content filtering software needs lots of CPU or memory.
-
-Major changes with snapshot-20000528
-====================================
-
-Specify "body_checks = regexp:/etc/postfix/body_checks" for a quick
-and dirty emergency content filter that looks at non-header lines
-one line at a time (including MIME headers inside the message body).
-Details in conf/sample-filter.cf.
-
-This version introduces a new queue manager with a clever scheduler
-by Patrik Rak that allow mailing list deliveries be pre-empted by
-non-list mail, while preserving correct average delivery delays.
-The queue manager is build as nqmgr. It needs further testing.
-
-Major changes with snapshot-20000514
-====================================
-
-LaMont Jones and Patrik Rak reported two different scenarios in
-which pipelined SMTP sessions could time out forever. Postfix now
-automatically flushes delayed SMTP commands/replies to prevent
-sender delays from accumulating too much.  For example, client-side
-delays happen when a client does DNS lookups to replace hostname
-aliases in a MAIL FROM or RCPT TO commands; server-side delays
-happen when an UCE restriction involves DNS lookup, or when a server
-generates a tarpit delay.
-
-Incompatible changes with snapshot-20000507
-===========================================
-
-As required by RFC 822, Postfix now inserts a generic destination
-message header when no destination header is present.  The text is
-specified via the undisclosed_recipients_header configuration
-parameter (default:  "To: undisclosed-recipients:;").
-
-The Postfix sendmail command treats a line with only `.' as
-the end of input, for the sake of sendmail compatibility. To disable
-this feature, specify the sendmail-compatible `-i' or `-oi' flags
-on the sendmail command line.
-
-For the sake of Sendmail compatibility, the Postfix SMTP client
-skips over SMTP servers that greet with a 4XX or 5XX reply code,
-treating them as unreachable servers.  To obtain prior behavior
-(4XX=retry, 5XX=bounce), specify "smtp_skip_4xx_greeting = no" and
-"smtp_skip_5xx_greeting = no".
-
-The read/write interface underneath VSTREAMs has been extended with
-parameters that specify a read/write timeout and application context.
-This should make it easier to plug in encryption modules such as TLS.
-
-Major changes with snapshot-20000507
-====================================
-
-Better documentation of Postfix lookup tables, including descriptions
-of how to use regular expressions in Postfix lookup tables.
-
-Updated mysql and LDAP client code with fixes and improvements.
+The pipe delivery agent has a configurable end-of-line attribute.
+Specify "pipe ... eol=\r\n" for delivery mechanisms that require
+CRLF record delimiters. The eol attribute understands the following
+C-style escape sequences:  \a \b \f \n \r \t \v \nnn \\.
 
 In master.cf you can selectively override main.cf configuration
 parameters, for example: "smtpd -o myhostname=foo.com".
@@ -404,35 +323,6 @@ connections to a specific local interface. Or override the default
 setting in master.cf with "smtp -o smtp_bind_address=x.x.x.x".
 For now, you must specify a numeric IP address.
 
-Preliminary LMTP client support over TCP with connection caching.
-Support for LMTP over UNIX-domain sockets will be added later as
-an enhancement to the transport table syntax. See the LMTP_README
-file for more details.
-
-By the way, LMTP client-side connection caching is a good example
-for how to do the same in the SMTP client.
-
-Preliminary support for SASL authentication, both in the SMTP server
-and in the SMTP client. See the SASL_README file for more details.
-
-The pipe delivery agent has a configurable end-of-line attribute.
-Specify "pipe ... eol=\r\n" for delivery mechanisms that require
-CRLF record delimiters. The eol attribute understands the following
-C-style escape sequences:  \a \b \f \n \r \t \v \nnn \\.
-
-Incompatible changes with snapshot-20000309
-===========================================
-
-This release is mainly to have a reference point after reorganizing
-the cleanup daemon, and before adding some major contributions from
-other people.
-
-Major changes with snapshot-20000309
-====================================
-
-Questionable feature: with "smtp_skip_5xx_greeting = yes", Postfix
-emulates behavior found in some other MTAs. 
-
 Questionable feature: with "smtp_always_send_ehlo = yes", the SMTP
 client sends EHLO regardless of the content of the SMTP server's
 greeting.
@@ -441,60 +331,9 @@ Specify "-d key" to postalias or postmap in order to remove one
 key. This still needs to be generalized to multi-key removal (e.g.,
 read keys from stdin).
 
-The manual pages in Postfix configuration files no longer contain
-troff formatting codes.  The text is now generated from prototype
-files in a new "proto" subdirectory.
-
-Incompatible changes with postfix-19991231:
-===========================================
-
-- The SMTP server no longer forwards mail from untrusted clients
-with sender-specified routing (stuff[@%!]stuff[@%!]stuff) through
-destinations that are authorized by the relay_domains parameter.
-This closes a loophole that exploits trust relationships between
-hosts.  Example:  a trusted backup MX host forwards junk mail to
-a primary MX host which forwards the junk to the Internet. Specify
-"allow_untrusted_routing = yes" to restore the old behavior.
-
-- The SMTP server no longer forwards mail with sender-specified
-routing (stuff[@%!]stuff[@%!]stuff) through destinations that are
-authorized by the permit_mx_backup feature. This change is under
-control by the allow_untrusted_routing parameter discussed above.
-
-- In order to support the above, the data structure and protocol
-of the trivial-rewrite service was changed. This means you must
-re-compile and re-link existing software that uses the Postfix
-resolve_clnt interface.
-
-- As a side effect of the above, an address from an untrusted client
-with @ in the localpart (user@remote@here) no longer bounces with
-"user unknown" but instead is rejected with "relay access denied".
-
-- Incompatible SMTPD access map changes:
-
-  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.
-
-  An empty right-hand sides still mean OK, but Postfix will log a
-  warning in order to discourage such usage.
-
-  You can no longer use virtual, canonical or aliases tables as
-  SMTPD access maps. Use the local_recipient_maps feature instead.
-
-- Recipient addresses may no longer begin with `-'. In order to
-get the old behavior, specify "allow_min_user = yes" in main.cf.
-
-- Incompatible transport map changes:
-
-  Transport map entries override mydestination.  If you use transport
-  maps, it is better to always have explicit entries for all domain
-  names you have in $mydestination.  See the html/faq.html sections
-  for firewalls and intranets.
-
-  The nexthop information given to a local delivery agent may have
-  changed.  This information was never intended to be used as a
-  next-hop destination.
+Comments in Postfix configuration files no longer contain troff
+formatting codes.  The text is now generated from prototype files
+in a new "proto" subdirectory.
 
 Major changes with postfix-19991231:
 ====================================
index 22f3d324c482f9de77c6040eb0588c21082a1292..f623d28786bcea0bf4f4b1a11d54f9293636599c 100644 (file)
@@ -5,11 +5,11 @@ 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).
+The only anomalies in this scheme are that (1) message header_checks
+and body_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
index d793787e8946e57d0c4c8cf0c17c6ea966a15fce..6567ab4e0cef5f8488953b1ee6c70563853bbd45 100644 (file)
@@ -62,11 +62,14 @@ Reportedly, Microsoft Internet Explorer version 5 requires the
 non-standard SASL LOGIN authentication method. To enable this
 authentication method, specify ``./configure --enable-login''.
 
-Reportedly, older Microsoft software mis-implements the AUTH
-protocol, and requires that the server replies to EHLO with
-"250-AUTH=stuff..." instead of "250-AUTH stuff...". To accomodate
-such clients, set "allow_broken_auth_clients = yes" in the main.cf
-file.
+Older Microsoft SMTP client software implements a non-standard 
+version of the AUTH protocol syntax, and expects that the SMTP
+server replies to EHLO with "250 AUTH=stuff" instead of "250 AUTH
+stuff".  To accomodate such clients in addition to conformant
+clients, set "broken_sasl_auth_clients = yes" in the main.cf file.
+
+The Postfix SMTP client is backwards compatible with SMTP servers
+that use the non-standard AUTH protocol syntax.
 
 Building Postfix with SASL authentication support
 =================================================
@@ -78,14 +81,14 @@ and that the Cyrus SASL libraries are in /usr/local/lib.
 On some systems this generates the necessary Makefile definitions:
 
     % make tidy # if you have left-over files from a previous build
-    % make makefiles CCARGS=-DUSE_SASL_AUTH" -I/usr/local/include" \
+    % make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include" \
        AUXLIBS="-L/usr/local/lib -lsasl"
 
 On Solaris 2.x you need to specify run-time link information,
 otherwise ld.so will not find the SASL shared library:
 
     % make tidy # if you have left-over files from a previous build
-    % make makefiles CCARGS=-DUSE_SASL_AUTH" -I/usr/local/include" \
+    % make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include" \
        AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lsasl"
 
 Enabling SASL authentication in the Postfix SMTP server
index 280c4c224074c211c5cae43d8f6c8d158376e2c8..04708b4df95c9055bbe5b64e64e82de0f6e4ca83 100644 (file)
@@ -7,55 +7,30 @@ expanded via :include:).
 
 postconf -f filename
 
-more general relocated feature - perhaps better to bounce recipients
+get rid of the relocated feature - perhaps better to bounce recipients
 at the SMTP port.
 
-use $mydomain when hostname is not FQDN.
-
-generic daemon that listens on fifo and runs command
-
 make sendmail/smtpd/cleanup output directory/fifo configurable
 
 if postdrop scrutinizes input, skip the overhead in the pickup
 daemon.
 
-luser relay
-
 add a threshold to sendmail etc. stderr logging, so that class
 "info" messages don't go to stderr.
 
-need a configurable mailbox locking method with system-specific
-default, so people don't have to recompile just to turn of fcntl()
-locks to work around SUN mailtool.
-
 implement an UCE control to accept mail if the sender domain sender
 lists us as MX host (rafal wiosna). By the same token, implement
 a control to accept mail when the client hostname/parent domain
 lists us as their MX host.
 
-with recipient delimiter enabled, append the unmatched recipient
-of @virtual.domain patterns as extension to right-hand recipient,
-for qmail-like virtual mapping.
-
 received: headers should be generated by the cleanup daemon, and
 client attributes ("with", "from", etc.) should be passed along
 with the message. This guarantees that forwarded/aliased mail gets
 stamped with the queue ID.
 
-trivial-rewrite etc.: after reload, close the listen socket and
-wait until all clients disconnect.
-
-In qmgr_entry.c, turn off random walk by default.
-
 toss double-bounce mail even when mail for the local machine is
 redirected to another box. See mail_addr_double_bounce().
 
-represent peer as object, not as name + addr arguments
-
-ignore sender: header when different from envelope?
-
-smtp client: optionally log every MX host contacted
-
 remote showq access (cookie in maildrop or print some text to inform
 the user)
 
@@ -63,48 +38,23 @@ defer: explain mail was bounced after N days
 
 multiple rewrite processes?
 
-log relay address in addition to host.
-
 gethostbyaddr() uses native name services, which can be slow.
 
 can we detect a client that ignores error responses?
 
 way to block inbound mail based on recipient suffix?
 
-when client begins with non-SMTP data, log warning
-
-when non-SMTP follows ".", log warning.
-
-On linux syslogd needs -/file/name
-
 can Postfix implement one switchboard instead of having all these
 little lookup tables?
 
 make canonical/virtual/etc. table lookup order configurable
 
-allow /file/name or maptype_mapname in $mydestination
-
-make protocol errors soft errore? There are a lot of broken mailers
-out there that sometimes croak and sometimes work.
-
-require @ in sender/rcpt (another restriction)
-
-figure out a way to pump recipients into qmgr before concurrency
-starts to drop.
-
 pass on client etc/ attributes along with message to delivery agent
 
-pass on configurable info into external process environment
-
 scrutinize file opens in delivery agents just like in qmgr (better:
 open the file and see if someone compromised the vmailer account
 and is racing against us).
 
-cleanup: don't run out of memory with large amounts of bcc addresses
-
-cleanup: permit non-empty extra segment, so that mail posting
-software can pass in bcc recipients.
-
 suspend/resume signals + master status (suspended/running) in PID
 file.  Maybe use FIFO instead. But, that means requests do not
 arrive when the master is stuck.
@@ -134,24 +84,9 @@ access.
 
 trivial-rewrite: optionally, use DNS to fully qualify hostnames.
 
-smtp: optionally deal with MX records containing an address instead
-of a name.
-
 pickup/cleanup/qmgr/local: add options record to control internal
 features such as canonical/virtual mapping, VERPs etcetera.
 
-smtpd: when deciding if a destination is local, also look at the
-virtual map. Perhaps we should move canonical and virtual lookups
-back into the rewrite service, but under a different name, so they
-do not get in the way if we do not want them.
-
-Queue manager: do not allocate queue slots when a destination
-already has more than some threshold. This is to prevent a dead or
-slow destination from filling up the queue manager's active queue,
-preventing delivery to other destinations. However, such `fairness'
-strategies should not cause Postfix to lose the benchmark race, so
-we must be fair and smart at the same time :-)
-
 Add hook for (domain, user database) support. This is needed if
 you have lots of real domains and can't afford a separate master.cf
 delivery agent entry for each domain.
@@ -159,9 +94,6 @@ delivery agent entry for each domain.
 Add support for DBZ databases, using the code from INN. Reportedly,
 GDB handles large numbers of keys poorly.
 
-Make the number of time bits in the queue ID configurable, or at
-least a little larger.
-
 Change the front-end to cleanup protocol so that the front-end
 sends the expected message size, and so that the cleanup service
 can report if there is enough space. This is useful only for the
@@ -196,40 +128,11 @@ postfix-script: detect and/or build missing alias database. In
 order to do this we must extract the alias_maps parameter from the
 main.cf file, and create any missing files with the right ownerships.
 
-SunOS 5.4 sendmail seems to include the null byte in alias keys
-and values, like almost every UNIX system; SunOS 5.5 sendmail does
-not include these nulls.  Need to add support for SunOS 5.4.  NIS
-alias maps always include the null terminator...
-
 implement the return-receipt-to notification service.
 
-Implement real address rewriting.
-
-default alias for mail to non-existent users. How useful is this
-when the postmaster already gets notices of mail that could not be
-delivered by the local mail system? And how do we pass around the
-original envelope recipient once it has been "aliased" to the
-address for non-existent users?
-
-owner-default alias to capture all mailing list errors.  Or perhaps
-they should just set up the appropriate owner-foo aliases in their
-alias database?
-
-make mail_params module the main config interface; no calls from
-config.c to routines in mail_params.c
-
-resolve/rewrite clients should share connection
-
-postfix-script: make sure permissions of queue (and anything below)
-are sane.
-
 bounce/defer: provide attribute-value interface, for better logging
 (expanded-from etc.) and non-delivery reports.
 
-Postfix-Options: header, to turn on qmail-like VERPs. But, these
-must be accessible only for locally-posted mail (not mail that
-arrives via UUCP).
-
 Maintain per-client short-term host status, so we can slow down
 unreasonable clients
 
@@ -248,27 +151,10 @@ True ETRN means kick the host out of the queue manager's "dead
 hosts" table & move mail from the "hold" queue for that site to
 the incoming queue.
 
-Option to make a copy of all mail passing through the mail system.
-
-The message ID is built by concatenating the time of day in seconds
-with the queue id. We must ensure that a queue id is unique for at
-least one second, otherwise multiple messages will have the same
-message ID. Queue ids will always collide after a while. The NFS
-generation number for the queue file would be useful, but there is
-no portable interface to get it, and we cannot depend on the system
-having NFS support enabled.  If a 1-microsecond resolution is
-sufficient, we could compose the queue ID from the inode number
-plus 6 decimal digits or 5 hex ones for the time in microseconds.
-Or, use a smarter encoding with more bits per character.
-
 postfix-script: make sure that each queue file matches its file id
 or we might lose mail.
 
 postfix-script: do database fixups as the unprivileged user
 
-Put a version file in the conf directory or add option to vmail
-control command to print the version (requires vmconf tool that
-can query main.cf.).
-
 Maintain a pool of pre-allocated queue files, to eliminate file
 creation and deletion overhead.
index ba5b0454006e28ea5f62a576ae3e4cfb10466107..e6fbd56e4f5db8405c4a592e3cd2977d8b32a26f 100644 (file)
@@ -2,3 +2,5 @@ In order to receive mail via UUCP, your system needs to have an
 rmail command installed. A minimal rmail command can be found in
 the "auxiliary/rmail" directory. Install the command, mode 755, in
 a place that can be found by the UUCP "uuxqt" command.
+
+In order to send mail via UUCP, see html/faq.html.
diff --git a/postfix/VIRTUAL_README b/postfix/VIRTUAL_README
deleted file mode 100644 (file)
index 2553125..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-[Code contribued by Andrew McNamara ]
-
-Code created by Andrew McNamara <andrew@connect.com.au> and adapted to
-snapshot 20001121 by Xavier Beaudouin.
-
-Code is maintened now by Xavier Beaudouin <kiwi@oav.net>
-
-[Original Message]
-I've run out of time to fiddle further at the moment, so I've decided to
-post my virtual local delivery agent. Note that this is still a work in
-progress, so don't bet your business on it.
-
-I'll repeat what I said last time:
-
-   This code is designed for ISP's who offer virtual mail hosting.  It
-   looks up the location, uid and gid of user mailboxes via separate maps,
-   and the mailbox location map can specify either mailbox or maildir
-   delivery (controlled by trailing slash on mailbox name).
-
-   The agent does not support aliases or .forwards (use the virtual table
-   instead), and therefore doesn't support file or program aliases. This
-   choice was made to simplify and streamline the code (it allowed me to
-   dispense with 70% of local's code - mostly the bits that are a security
-   headache) - if you need this functionality, this agent isn't for you.
-
-   It also doesn't support writing to a common spool as root and then
-   chowning the mailbox to the user - I felt this functionality didn't fit
-   with my overall aims.
-
-Some other notes:
-
-- It's still called "virtual" - I had some concerns that this would
-  confuse people, but I'll leave that call up to Wietse - if he wants
-  to integrate it, he can specify the name.
-
-- I've retained the three separate map lookups at this time. When
-  postfix supports maps that return multiple values, we can consider
-  changing it then.
-
-- Specify "virtual:" as the target in the transport table for domains
-  for which you want this agent used.
-
-- The attached file is a gzipped tar that should be unpacked in the
-  base postfix directory (where the INSTALL and HISTORY files live) -
-  it adds a "virtual" subdirectory, and a "virtual.patch" file. The
-  patch updates the top level Makefile.in to build the new agent, and
-  global/mail_params.h to add the new config parameters.
-
-New config options are:
-
-virtual_mailbox_base
-
-    Specifies a path that is prepended to all mailbox paths. This is
-    a safety measure to ensure an out of control map doesn't litter the
-    filesystem with mailboxes (or worse). While it could be set to "/",
-    this isn't recommended.
-
-virtual_mailbox_maps
-
-    Recipients are looked up in this map to determine the path to their
-    mailbox. If the returned path ends in a slash ("/"), maildir-style
-    delivery is carried out, otherwise the path is assumed to specify a
-    mailbox file. Note that virtual_mailbox_base is unconditionally
-    prepended to this path.
-
-virtual_minimum_uid
-
-    Specifies a minimum uid that will be accepted as a return from a
-    virtual_uid_maps lookup. Returned values less than this will be
-    rejected, and the message will be deferred.
-
-virtual_uid_maps
-
-    Recipients are looked up in this map to determine the UID to be
-    used when writing to the target mailbox.
-
-virtual_gid_maps
-
-    Recipients are looked up in this map to determine the GID to be
-    used when writing to the target mailbox.
-
-virtual_usedotlock
-
-    Use dot-locking when writing to mailboxes - defaults to off.
-
-[ - Exemple configuration - ]
-
-In main.cf file :
---/---
- virtual_mailbox_base = /var/mail/vhosts
- virtual_mailbox_maps = dbm:/etc/postfix/vmailbox
- virtual_minimum_uid = 100
- virtual_uid_maps = dbm:/etc/postfix/vuid
- virtual_gid_maps = dbm:/etc/postfix/vgid
- virtual_usedotlock = no
---/---
-
-In vmailbox file :
-
---/---
-testuser@fakedom.com testuser/
---/---
-
-In vuid file :
-
---/---
-testuser@fakedom.com 5000
---/---
-
-In vgid file :
-
---/---
-testuser@fakedom.com 5000
---/---
-
-Don't forget to add in master.cf the entry for the agent, that should be
-like :
-
---/---
-virtual     unix  -       n       n       -       -       virtual
---/---
-
-NOTES :
--------
-
-1- Don't forget to add dbm:/etc/posfix/vmailbox into your 
-local_recipent_maps in main.cf like :
-
---/---
-local_recipient_maps = $alias_maps dbm:/etc/posfix/vmailbox unix:passwd.byname
---/---
-
-2- If you use only the virtual localdelivery you can add the following line
-into main.cf
-
---/---
-mailbox_transport = virtual
---/---
-
-Otherwise you can use transport_maps :
-
-In main.cf file :
-
---/---
-transport_maps=dbm:/etc/postfix/transport
---/---
-
-In transport file :
-
---/---
-fakedom.com    virtual:
---/---
-
-
index a8a9d354f2b90b8e839d1a728b8700e210e5536b..78f93f18859eaba3af838c6c9d7cf7e3b03182cf 100644 (file)
 #        REJECT Reject the address etc. that matches the pattern. A
 #               generic error response message is generated.
 # 
-#        OK
+#        OK     Accept the address etc. that matches the pattern.
 # 
-#        Any other text
-#               Accept the address etc. that matches the pattern.
+#        restriction...
+#               Apply the named UCE  restriction  (permit,  reject,
+#               reject_unauth_destination, and so on).
 # 
 # REGULAR EXPRESSION TABLES
-#        This section describes how the table lookups  change  when
+#        This  section  describes how the table lookups change when
 #        the table is given in the form of regular expressions. For
-#        a description of regular expression lookup  table  syntax,
+#        a  description  of regular expression lookup table syntax,
 #        see regexp_table(5) or pcre_table(5).
 # 
-#        Each  pattern  is  a regular expression that is applied to
+#        Each pattern is a regular expression that  is  applied  to
 #        the entire string being looked up. Depending on the appli-
-#        cation,  that  string  is  an  entire  client hostname, an
+#        cation, that string  is  an  entire  client  hostname,  an
 #        entire client IP address, or an entire mail address. Thus,
-#        no  parent  domain  or  parent network search is done, and
-#        user@domain mail addresses are not broken  up  into  their
+#        no parent domain or parent network  search  is  done,  and
+#        user@domain  mail  addresses  are not broken up into their
 #        user@ and domain constituent parts.
 # 
-#        Patterns  are  applied  in  the  order as specified in the
-#        table, until a pattern is found that  matches  the  search
+#        Patterns are applied in the  order  as  specified  in  the
+#        table,  until  a  pattern is found that matches the search
 #        string.
 # 
-#        Actions  are the same as with normal indexed file lookups,
-#        with the additional feature that parenthesized  substrings
-#        from  the pattern can be interpolated as $1, $2 and so on.
+#        Actions are the same as with normal indexed file  lookups,
+#        with  the additional feature that parenthesized substrings
+#        from the pattern can be interpolated as $1, $2 and so  on.
 # 
 # BUGS
-#        The table format does not understand quoting  conventions.
+#        The  table format does not understand quoting conventions.
 # 
 #                                                                 2
 # 
 #        regexp_table(5) format of POSIX regular expression tables
 # 
 # LICENSE
-#        The  Secure  Mailer  license must be distributed with this
+#        The Secure Mailer license must be  distributed  with  this
 #        software.
 # 
 # AUTHOR(S)
index 38ae9fcd806118c3c1ec653c03ebba01f27a17c7..ee1c90c708ab1774660fbb051cabce7b31e1d1be 100644 (file)
@@ -4,6 +4,9 @@
 # The general format is lines with parameter = value pairs. Lines
 # that begin with whitespace continue the previous line. A value can
 # contain references to other $names or ${name}s.
+#
+# NOTE - CHANGE NO MORE THAN 2-3 PARAMETERS AT A TIME, AND TEST IF
+# POSTFIX STILL WORKS AFTER EVERY CHANGE.
 
 # SOFT BOUNCE
 #
@@ -115,14 +118,85 @@ mail_owner = postfix
 # a name matches a lookup key.  Continue long lines by starting the
 # next line with whitespace.
 #
-# DO NOT LIST VIRTUAL DOMAINS HERE. LIST THEM IN THE VIRTUAL FILE
-# INSTEAD. BE SURE TO READ THE ENTIRE VIRTUAL MANUAL PAGE.
-#
 #mydestination = $myhostname, localhost.$mydomain
 #mydestination = $myhostname, localhost.$mydomain $mydomain
 #mydestination = $myhostname, localhost.$mydomain, $mydomain,
 #      mail.$mydomain, www.$mydomain, ftp.$mydomain
 
+# TRUST AND RELAY CONTROL
+
+# The mynetworks parameter specifies the list of "trusted" SMTP
+# clients that have more privileges than "strangers".
+#
+# In particular, "trusted" SMTP clients are allowed to relay mail
+# through Postfix.  See the smtpd_recipient_restrictions parameter
+# in file sample-smtpd.cf.
+#
+# You can specify the list of "trusted" network addresses by hand
+# or you can let Postfix do it for you (which is the default).
+#
+# By default (mynetworks_style = subnet), Postfix "trusts" SMTP
+# clients in the same IP subnetworks as the local machine.
+# On Linux, this does works correctly only with interfaces specified
+# with the "ifconfig" command.
+# 
+# Specify "mynetworks_style = class" when Postfix should "trust" SMTP
+# clients in the same IP class A/B/C networks as the local machine.
+# Don't do this with a dialup site - it would cause Postfix to "trust"
+# your entire provider's network.  Instead, specify an explicit
+# mynetworks list by hand, as described below.
+#  
+# Specify "mynetworks_style = host" when Postfix should "trust"
+# only the local machine.
+# 
+# mynetworks_style = class
+# mynetworks_style = subnet
+# mynetworks_style = host
+
+# Alternatively, you can specify the mynetworks list by hand, in
+# which case Postfix ignores the mynetworks_style setting.
+#
+# Specify an explicit list of network/netmask 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.
+#
+#mynetworks = 168.100.189.0/28, 127.0.0.0/8
+#mynetworks = $config_directory/mynetworks
+
+# The relay_domains parameter restricts what clients this mail system
+# will relay mail from, or what destinations this system will relay
+# mail to.  See the smtpd_recipient_restrictions restriction in the
+# file sample-smtpd.cf for detailed information.
+#
+# By default, Postfix relays mail
+# - from "trusted" clients whose IP address matches $mynetworks, 
+# - from "trusted" clients matching $relay_domains or subdomains thereof,
+# - from untrusted clients to destinations that match $relay_domains
+#   or subdomains thereof, except addresses with sender-specified routing.
+# The default relay_domains value is $mydestination.
+# 
+# In addition to the above, the Postfix SMTP server by default accepts mail
+# that Postfix is final destination for:
+# - destinations that match $inet_interfaces,
+# - destinations that match $mydestination
+# - destinations that match $virtual_maps.
+# These destinations do not need to be listed in $relay_domains.
+# 
+# Specify a list of hosts or domains, /file/name patterns or type:name
+# lookup tables, separated by commas and/or whitespace.  Continue
+# long lines by starting the next line with whitespace. A file name
+# is replaced by its contents; a type:name table is matched when a
+# (parent) domain appears as lookup key.
+#
+# NOTE: Postfix will not automatically forward mail for domains that
+# list this system as their primary or backup MX host. See the
+# permit_mx_backup restriction in the file sample-smtpd.cf.
+#
+#relay_domains = $mydestination
+
 # INTERNET OR INTRANET
 
 # The relayhost parameter specifies the default host to send mail to
@@ -322,53 +396,6 @@ mail_owner = postfix
 #header_checks = regexp:/etc/postfix/filename
 #header_checks = pcre:/etc/postfix/filename
 
-# The relay_domains parameter restricts what clients this mail system
-# will relay mail from, or what destinations this system will relay
-# mail to.  See the smtpd_recipient_restrictions restriction in the
-# file sample-smtpd.cf.
-#
-# By default, Postfix relays mail
-# - from trusted clients whose IP address matches $mynetworks, 
-# - from trusted clients matching $relay_domains or subdomains thereof,
-# - from untrusted clients to destinations that match $relay_domains
-#   or subdomains thereof, except addresses with sender-specified routing.
-# The default relay_domains value is $mydestination.
-# 
-# In addition to the above, the Postfix SMTP server by default accepts mail
-# that Postfix is final destination for:
-# - destinations that match $inet_interfaces,
-# - destinations that match $mydestination
-# - destinations that match $virtual_maps.
-# These destinations do not need to be listed in $relay_domains.
-# 
-# Specify a list of hosts or domains, /file/name patterns or type:name
-# lookup tables, separated by commas and/or whitespace.  Continue
-# long lines by starting the next line with whitespace. A file name
-# is replaced by its contents; a type:name table is matched when a
-# (parent) domain appears as lookup key.
-#
-# NOTE: Postfix will not automatically forward mail for domains that
-# list this system as their primary or backup MX host. See the
-# permit_mx_backup restriction in the file sample-smtpd.cf.
-#
-#relay_domains = $mydestination
-
-# The mynetworks parameter specifies the list of networks that are
-# local to this machine.  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.
-#
-# 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. If you want stricter control, specify a
-# 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.
-#
-#mynetworks = 168.100.189.0/28, 127.0.0.0/8
-#mynetworks = $config_directory/mynetworks
-
 # FAST ETRN SERVICE
 #
 # Postfix maintains per-destination logfiles with information about
@@ -411,10 +438,11 @@ mail_owner = postfix
 # raise eyebrows.
 # 
 # Each message delivery transport has its XXX_destination_concurrency_limit
-# parameter.  The default is $default_destination_concurrency_limit.
+# parameter.  The default is $default_destination_concurrency_limit for
+# most delivery transports. For the local delivery agent the default is 2.
 
-local_destination_concurrency_limit = 2
-default_destination_concurrency_limit = 10
+#local_destination_concurrency_limit = 2
+#default_destination_concurrency_limit = 10
 
 # DEBUGGING CONTROL
 #
index 15deb0142e1bd5e4b4b527b9d5d1d82d829bea13..e00d7c6834977b459a9a35e0d79b10223a68e326 100644 (file)
@@ -80,6 +80,7 @@ smtp    unix  -       -       n       -       -       smtp
 showq     unix n       -       n       -       -       showq
 error     unix -       -       n       -       -       error
 local    unix  -       n       n       -       -       local
+virtual          unix  -       n       n       -       -       virtual
 lmtp     unix  -       -       n       -       -       lmtp
 cyrus    unix  -       n       n       -       -       pipe
     flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user}
index 25235a208a7ddb9dca2919f91c293a9c2fc73fc4..2c5d43ae21c3b274e5203090b2ee30fd66c46c2b 100755 (executable)
@@ -145,7 +145,9 @@ reload)
                exit 1
        }
        $INFO refreshing the Postfix mail system
+       $command_directory/postsuper active || exit 1
        kill -HUP `sed 1q pid/master.pid`
+       $command_directory/postsuper &
        ;;
 
 flush)
@@ -245,6 +247,8 @@ EOF
        (echo "$found" | grep bounce >/dev/null) || missing="$missing bounce"
        (echo "$found" | grep defer >/dev/null)  || missing="$missing defer"
        (echo "$found" | grep flush >/dev/null)  || missing="$missing flush"
+       (echo "$found" | grep incoming>/dev/null)|| missing="$missing incoming"
+       (echo "$found" | grep deferred>/dev/null)|| missing="$missing deferred"
        test -n "$missing" && {
                $WARN fixing main.cf hash_queue_names for missing $missing
                $command_directory/postconf -e hash_queue_names="$found$missing"
@@ -252,7 +256,8 @@ EOF
 
        # See if all queue files are in the right place.
 
-       $command_directory/postsuper || exit 1
+       $command_directory/postsuper active
+       $command_directory/postsuper &
 
        find corrupt -type f -exec $WARN damaged message: {} \;
 
index 2cf7f5c383b09ca80635d5c83f8692fcbd5775f1..a635ef679d787e090b01bc2c84afa5f958e30795 100755 (executable)
@@ -145,7 +145,9 @@ reload)
                exit 1
        }
        $INFO refreshing the Postfix mail system
+       $command_directory/postsuper active || exit 1
        kill -HUP `sed 1q pid/master.pid`
+       $command_directory/postsuper &
        ;;
 
 flush)
@@ -246,6 +248,8 @@ EOF
        (echo "$found" | grep bounce >/dev/null) || missing="$missing bounce"
        (echo "$found" | grep defer >/dev/null)  || missing="$missing defer"
        (echo "$found" | grep flush >/dev/null)  || missing="$missing flush"
+       (echo "$found" | grep incoming>/dev/null)|| missing="$missing incoming"
+       (echo "$found" | grep deferred>/dev/null)|| missing="$missing deferred"
        test -n "$missing" && {
                $WARN fixing main.cf hash_queue_names for missing $missing
                $command_directory/postconf -e hash_queue_names="$found$missing"
@@ -253,8 +257,8 @@ EOF
 
        # See if all queue files are in the right place.
 
-
-       $command_directory/postsuper || exit 1
+       $command_directory/postsuper active
+       $command_directory/postsuper &
 
        find corrupt -type f -exec $WARN damaged message: {} \;
 
index 00620b31121a5250a94979632a04257206086a4a..4f8a504d6078d6fff92c5e6b1d289df67a1e18b6 100644 (file)
@@ -67,3 +67,8 @@
 # ldap_open(3) man page.
 #
 #ldap_dereference = 0
+
+# The ldap_domain parameter limits the LDAP searches to just things in
+# (exactly) the specified list of domains.
+#
+#ldap_domain =
index d7b7e0268756dd879a18306887c08fb570745d85..f8ac3329ab876d0beea1cfd8f566adc9eea5de34 100644 (file)
@@ -187,7 +187,7 @@ mailbox_transport =
 fallback_transport =
 
 #
-# RATE CONTROLS
+# RESOURCE CONTROLS
 #
 
 # The local_destination_concurrency_limit parameter limits the number
@@ -200,6 +200,13 @@ fallback_transport =
 #
 local_destination_concurrency_limit = 2
 
+# The mailbox_size_limit parameter controls the maximal size of a
+# mailbox or maildir file (in fact, it limits the size of any file
+# that is written to upon local delivery) The default is 50 MBytes.
+# This limit must not be set smaller than the message size limit.
+# 
+mailbox_size_limit = 51200000
+
 # The local_destination_recipient_limit parameter limits the number
 # of recipients per local message delivery.  The default limit is
 # taken from the default_destination_recipient_limit parameter.
index ed7b57db4eeeefee2584cdb87f28b85027f34ce6..14f9e19b2c80aa34479c98021c2a5fbd43123e4e 100644 (file)
@@ -211,23 +211,41 @@ mydestination = $myhostname, localhost.$mydomain
 # myorigin = $mydomain
 myorigin = $myhostname
 
-# The mynetworks parameter specifies the list of networks that are
-# local to this machine.  The list is used by the anti-UCE software
-# to distinguish local clients from strangers. See permit_mynetworks
-# in the sample-smtpd.cf file.
-#
-# The mynetworks parameter specifies the list of networks that are
-# local to this machine.  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.
-#
-# 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. If you want stricter control, specify a
-# 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.
+# The mynetworks parameter specifies the list of "trusted" SMTP
+# clients that have more privileges than "strangers".
+#
+# In particular, "trusted" SMTP clients are allowed to relay mail
+# through Postfix.  See the smtpd_recipient_restrictions parameter
+# in file sample-smtpd.cf.
+#
+# You can specify the list of "trusted" network addresses by hand
+# or you can let Postfix do it for you (which is the default).
+#
+# By default (mynetworks_style = subnet), Postfix "trusts" SMTP
+# clients in the same IP subnetworks as the local machine.
+# 
+# Specify "mynetworks_style = class" when Postfix should "trust" SMTP
+# clients in the same IP class A/B/C networks as the local machine.
+# Don't do this with a dialup site - it would cause Postfix to "trust"
+# your entire provider's network.  Instead, specify an explicit
+# mynetworks list by hand, as described below.
+#  
+# Specify "mynetworks_style = host" when Postfix should "trust"
+# only the local machine.
+# 
+# mynetworks_style = class
+# mynetworks_style = subnet
+# mynetworks_style = host
+
+# Alternatively, you can specify the mynetworks list by hand, in
+# which case Postfix ignores the mynetworks_style setting.
+#
+# Specify an explicit list of network/netmask 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.
 #
 #mynetworks = 168.100.189.0/28, 127.0.0.0/8
 
index 56f30180023cbaa411fc24c8f5b5566f42e7c51f..ec7714d60a79a6de323e3a620e295b270dcca1c7 100644 (file)
@@ -101,6 +101,45 @@ smtpd_hard_error_limit = 100
 # UCE RESTRICTIONS
 #
 
+# The mynetworks parameter specifies the list of "trusted" SMTP
+# clients that have more privileges than "strangers".
+#
+# In particular, "trusted" SMTP clients are allowed to relay mail
+# through Postfix.  See the smtpd_recipient_restrictions parameter
+# in file sample-smtpd.cf.
+#
+# You can specify the list of "trusted" network addresses by hand
+# or you can let Postfix do it for you (which is the default).
+#
+# By default (mynetworks_style = subnet), Postfix "trusts" SMTP
+# clients in the same IP subnetworks as the local machine.
+# 
+# Specify "mynetworks_style = class" when Postfix should "trust" SMTP
+# clients in the same IP class A/B/C networks as the local machine.
+# Don't do this with a dialup site - it would cause Postfix to "trust"
+# your entire provider's network.  Instead, specify an explicit
+# mynetworks list by hand, as described below.
+#  
+# Specify "mynetworks_style = host" when Postfix should "trust"
+# only the local machine.
+# 
+# mynetworks_style = class
+mynetworks_style = subnet
+# mynetworks_style = host
+
+# Alternatively, you can specify the mynetworks list by hand, in
+# which case Postfix ignores the mynetworks_style setting.
+#
+# Specify an explicit list of network/netmask 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.
+#
+#mynetworks = 168.100.189.0/28, 127.0.0.0/8
+#mynetworks = $config_directory/mynetworks
+
 # The smtpd_client_restrictions parameter specifies optional restrictions
 # on SMTP client host names and addresses.
 #
diff --git a/postfix/conf/sample-virtual.cf b/postfix/conf/sample-virtual.cf
new file mode 100644 (file)
index 0000000..d660d6b
--- /dev/null
@@ -0,0 +1,23 @@
+# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF
+# HERE JUST SERVES AS AN EXAMPLE.
+#
+# This file contains example settings of Postfix configuration
+# parameters that control virtual database lookups.
+
+# The virtual_maps parameter specifies optional lookup tables to
+# redirect specific addresses or even complete domains to another
+# address. This is typically used to implement virtual domain support.
+# 
+# By default, no address redirection is done. 
+#
+# If you use this feature, run "postmap /etc/postfix/virtual" to 
+# build the necessary DBM or DB file after change.
+#
+# It may take a minute or so before the change becomes visible.
+# Use "postfix reload" to eliminate the delay.
+#
+# virtual_maps = dbm:/etc/postfix/virtual
+# virtual_maps = hash:/etc/postfix/virtual
+# virtual_maps = hash:/etc/postfix/virtual, nis:virtual
+# virtual_maps = hash:/etc/postfix/virtual, netinfo:/virtual
+virtual_maps = 
index 9374acc1abe421595e29e13290e11b40856361ae..8f7e91ac162c250bc7978d9848f2abd384979eeb 100644 (file)
@@ -5,7 +5,7 @@ SHELL   = /bin/sh
 DAEMONS        =  bounce.8.html cleanup.8.html defer.8.html error.8.html local.8.html \
        lmtp.8.html master.8.html pickup.8.html pipe.8.html qmgr.8.html \
        showq.8.html smtp.8.html smtpd.8.html trivial-rewrite.8.html \
-       spawn.8.html flush.8.html 
+       spawn.8.html flush.8.html # nqmgr.8.html virtual.8.html
 COMMANDS= mailq.1.html newaliases.1.html postalias.1.html postcat.1.html \
        postconf.1.html postfix.1.html postkick.1.html postlock.1.html \
        postlog.1.html postdrop.1.html postmap.1.html sendmail.1.html \
@@ -51,6 +51,12 @@ local.8.html: ../src/local/local.c
 master.8.html: ../src/master/master.c
        srctoman $? | nroff -man | man2html | postlink >$@
 
+nqmgr.8.html: ../src/nqmgr/qmgr.c
+       srctoman $? | sed -e 's/qmgr[^_]/n&/' \
+                         -e 's/qmgr$$/n&/' \
+                         -e 's/QMGR[^_]/N&/' | \
+           nroff -man | man2html | postlink >$@
+
 pickup.8.html: ../src/pickup/pickup.c
        srctoman $? | nroff -man | man2html | postlink >$@
 
@@ -72,6 +78,9 @@ smtp.8.html: ../src/smtp/smtp.c
 smtpd.8.html: ../src/smtpd/smtpd.c
        srctoman $? | nroff -man | man2html | postlink >$@
 
+virtual.8.html: ../src/virtual/virtual.c
+       srctoman $? | nroff -man | man2html | postlink >$@
+
 trivial-rewrite.8.html: ../src/trivial-rewrite/trivial-rewrite.c
        srctoman $? | nroff -man | man2html | postlink >$@
 
index 383ba957e42fa161c6d4af1c9b6ddc78da81a95d..0818d204c6f093b3ec9030cc76b343c6a4b035d6 100644 (file)
@@ -94,36 +94,36 @@ ACCESS(5)                                               ACCESS(5)
        <b>REJECT</b> Reject the address etc. that matches the pattern. A
               generic error response message is generated.
 
-       <b>OK</b>
+       <b>OK</b>     Accept the address etc. that matches the pattern.
 
-       <i>Any</i> <i>other</i> <i>text</i>
-              Accept the address etc. that matches the pattern.
+       <i>restriction...</i>
+              Apply the named UCE  restriction  (<b>permit</b>,  reject,
+              <b>reject</b><i>_</i><b>unauth</b><i>_</i><b>destination</b>, and so on).
 
 <b>REGULAR</b> <b>EXPRESSION</b> <b>TABLES</b>
-       This section describes how the table lookups  change  when
+       This  section  describes how the table lookups change when
        the table is given in the form of regular expressions. For
-       a description of regular expression lookup  table  syntax,
+       a  description  of regular expression lookup table syntax,
        see <a href="regexp_table.5.html"><b>regexp</b><i>_</i><b>table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre</b><i>_</i><b>table</b>(5)</a>.
 
-       Each  pattern  is  a regular expression that is applied to
+       Each pattern is a regular expression that  is  applied  to
        the entire string being looked up. Depending on the appli-
-       cation,  that  string  is  an  entire  client hostname, an
+       cation, that string  is  an  entire  client  hostname,  an
        entire client IP address, or an entire mail address. Thus,
-       no  parent  domain  or  parent network search is done, and
-       <i>user@domain</i> mail addresses are not broken  up  into  their
+       no parent domain or parent network  search  is  done,  and
+       <i>user@domain</i>  mail  addresses  are not broken up into their
        <i>user@</i> and <i>domain</i> constituent parts.
 
-       Patterns  are  applied  in  the  order as specified in the
-       table, until a pattern is found that  matches  the  search
+       Patterns are applied in the  order  as  specified  in  the
+       table,  until  a  pattern is found that matches the search
        string.
 
-       Actions  are the same as with normal indexed file lookups,
-       with the additional feature that parenthesized  substrings
-       from  the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
+       Actions are the same as with normal indexed file  lookups,
+       with  the additional feature that parenthesized substrings
+       from the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so  on.
 
 <b>BUGS</b>
-       The table format does not understand quoting  conventions.
-
+       The  table format does not understand quoting conventions.
 
 
 
@@ -144,7 +144,7 @@ ACCESS(5)                                               ACCESS(5)
        <a href="regexp_table.5.html">regexp_table(5)</a> format of POSIX regular expression tables
 
 <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>
index 5ce551c0427d541510ef5e1fc4d8fa1d65df2a47..577a3c0323f223915198f435a3b861b3fff467b7 100644 (file)
@@ -57,6 +57,22 @@ or in order to resolve a destination.
 queue status. This is the program behind the <a
 href="mailq.1.html">mailq</a> command.
 
+<p>
+
+<li>The <a href="flush.8.html">flush</a> daemon improves the
+performance of the SMTP <b>ETRN</b> request, and of its command-line
+equivalent, <b>sendmail -qR</b><i>destination</i>, for selected
+destinations. For other destinations, Postfix silently falls
+back to the equivalent of <b>sendmail -q</b>.
+
+<p>
+
+<li>The <a href="spawn.8.html">spawn</a> daemon listens on a TCP
+port, UNIX-domain socket or FIFO, and runs non-Postfix commands on
+request, with the socket or FIFO connected to the standard input,
+output and error streams.  It is currently used only in an example
+of the Postfix external content filtering system.
+
 </ul>
 
 <hr>
index 19635f6f9bc32d4b9f71b3c7bb81515c088982c2..3333296b739fc64615c3978d83815801922c8ec7 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,25 @@ 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 authorized
+networks and in authorized domains.
+
+<p>
+
+Authorized client networks are defined by the <a
+href="#mynetworks">mynetworks</a> parameter. The default is to
+authorize all clients in the IP subnetworks that the local machine
+is attached to.
+
+<p>
+
+Authorized client domains are by defined by the <a
+href="uce.html#relay_domains"> relay_domains</a> configuration
+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>
 
@@ -286,17 +308,59 @@ top-level domain).
 <a name="mynetworks"> <h2> My own networks </h2> </a>
 
 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.
+somehow trusts. This information can be used by the <a href="uce.html">
+anti-UCE</a> features to recognize trusted SMTP clients that are
+allowed to relay mail through Postfix.
+
+<p>
+
+You can specify the list of trusted networks in the <b>main.cf</b>
+file, or you can let Postfix deduce the list for you. The default
+is to let Postfix do the work for you.
+
+<p>
+
+<dl>
+
+<dt> Default:
+
+<dd> <b>mynetworks_style = subnet</b>
+
+<p>
+
+<dt>The meaning of the styles is as follows:
 
 <p>
 
-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:
+<dl>
+
+<dt> <b>class</b> <dd> Trust SMTP clients in the class A/B/C networks
+that Postfix is connected to. <b>Don't do this with a dialup site
+- it would cause Postfix to "trust" your entire provider's network.
+Instead, specify an explicit mynetworks list by hand, as described
+below</b>.
+
+<p>
+
+<dt> <b>subnet</b> (default) <dd> Trust SMTP clients in the IP
+subnetworks that Postfix is connected to.
+
+<p>
+
+<dt> <b>host</b> <dd> Trust only the local machine.
+
+</dl>
+
+</dl>
+
+<p>
+
+Alternatively, you can specify the <b>mynetworks</b> list by hand,
+in which case Postfix ignores the <b>mynetworks_style</b> setting.
+To specify the list of trusted networks by hand, specify network
+blocks in CIDR (network/mask) notation, for example:
+
+<p>
 
 <dl>
 
@@ -304,6 +368,11 @@ to consider all their customer systems as local, so I use instead:
 
 </dl>
 
+<p>
+
+You can also specify the absolute pathname of a pattern file instead
+of listing the patterns in the <b>main.cf</b> file.
+
 <a name="inet_interfaces"> <h2> My own network addresses </h2> </a>
 
 The <b>inet_interfaces</b> parameter specifies all network interface
@@ -316,9 +385,14 @@ as if it is addressed to a domain listed in <b> $mydestination.
 
 The default is to listen on all active interfaces.  If you run
 mailers on virtual interfaces, you will have to specify what
-interfaces to listen on. This includes the non-virtual mailer that
-receives mail for the machine itself as well: it should never listen
-on the virtual interfaces or you would have a mailer loop.
+interfaces to listen on. 
+
+<p>
+
+You even have to specify explicit machine interfaces for the
+non-virtual mailer that receives mail for the machine itself: the
+non-virtual mailer should never listen on the virtual interfaces
+or you would have a mailer loop.
 
 <dl>
 
index a39b603afaf05c38ab7e3e8bf9ed0b862f3e2f3b..ed2a9e533d40e73a4a2bf2e002e393e0b6db3e42 100644 (file)
@@ -108,6 +108,20 @@ such as the popular <a href="faq.html#procmail">procmail</a> program.
 
 <p>
 
+<li>The <a href="virtual.8.html">virtual</a> delivery agent is a
+very much stripped down version of the local delivery agent that
+delivers to mailboxes only. This is the most secure Postfix delivery
+agent, because it does not aliases expansions and no .forward file
+expansions. 
+
+<p>
+
+This delivery agent can deliver mail for multiple domains, which
+makes it especially suitable for hosting lots of small domains on
+a single machine.
+
+<p>
+
 <li>The <a href="smtp.8.html">SMTP client</a> looks up a list of
 mail exchangers for the destination host, sorts the list by
 preference, and tries each address in turn until it finds a server
@@ -116,6 +130,15 @@ client processes running in parallel.
 
 <p>
 
+<li>The <a href="lmtp.8.html">LMTP client</a> speaks a protocol
+similar to SMTP. The client can connect to local or remote mailbox
+servers such as Cyrus. All the queue management is done by Postfix.
+The advantage of this setup is that one Postfix machine can feed
+multiple mailbox servers over LMTP. The opposite is true as well:
+one mailbox server can be fed over LMTP by multiple Postfix machines.
+
+<p>
+
 <li>The <a href="pipe.8.html">pipe mailer</a> is the outbound
 interface to other mail transports (the <a
 href="sendmail.1.html">sendmail</a> program is the inbound interface).
index 2a3d401f8c8ed83a2af12d8de8d51db2daa5aa5c..d36ab9919bd1c3c25761475fa750a2cacda4168e 100644 (file)
@@ -16,8 +16,8 @@ ERROR(8)                                                 ERROR(8)
        requests from the queue manager. Each request specifies  a
        queue  file,  a sender address, a domain or host name that
        is treated as the reason for non-delivery,  and  recipient
-       information.  This program expects to be run from the <a href="master.8.html"><b>mas-</b>
-       <b>ter</b>(8)</a> process manager.
+       information.  This program expects to be run from the <a href="master.8.html"><b>mas-</b></a>
+       <a href="master.8.html"><b>ter</b>(8)</a> process manager.
 
        The error mailer client forces all recipients  to  bounce,
        using  the  domain  or  host information as the reason for
index db0cfd95b0607fea7752b338db47070d882b0953..d48c5be2f10e30cadeb4160134e5dc8c97b541fd 100644 (file)
 
 <ul>
 
+<li><a href="#poppers">POP or IMAP problems</a>
+
+<li><a href="#warnings">Postfix warnings and error messages</a>
+
 <li><a href="#example_config">Example configurations</a>
 
 <li><a href="#sendmail_incompatibility">Sendmail incompatibility</a>
 
+<li><a href="#moby">Running hundreds of Postfix processes</a>
+
 <li><a href="#performance">Postfix performance</a>
 
 <li><a href="#receiving">Receiving mail via the network</a>
 
 <p>
 
+<a name="warnings"><h3>Postfix warnings and error messages</h3>
+
+<ul>
+
+<li><a href="#biff">What does "biff_notify: Connection refused" mean?</a>
+
+<li><a href="#nisdom">What does "NIS domain name not set - NIS lookups disabled" mean?</a>
+
+<li><a href="#dns-again">Mail stays queued with: Host not found, try again</a>
+
+<li><a href="#timeouts">Mail fails consistently with timeout or lost connection</a>
+
+<li><a href="#noalias">What does "fatal: open database /etc/aliases.db" mean?</a>
+
+<li><a href="#nosuid">sendmail has set-uid root file permissions, or is run from a set-uid root process</a>
+
+</ul>
+
+<p>
+
 <a name="example_config"><h3>Example configurations</h3>
 
 <ul>
@@ -72,6 +98,8 @@
 
 </ul>
 
+<p>
+
 <a name="sendmail_incompatibility"><h3>Sendmail incompatibility</h3>
 
 <ul>
@@ -99,11 +127,22 @@ distribution list</a>
 
 </ul>
 
+<a name="moby"><h3>Running hundreds of Postfix processes</h3>
+
+<ul>
+
+<li><a href="#moby-freebsd">Running hundreds of Postfix processes on FreeBSD</a>
+
+<li><a href="#moby-linux">Running hundreds of Postfix processes on Linux</a>
+
+</ul>
+
+
 <a name="performance"><h3>Postfix performance</h3>
 
 <ul>
 
-<li><a href="#incoming">Too much mail in the incoming queue</a>
+<li><a href="#incoming">Mail stays queued in the incoming queue</a>
 
 <li><a href="#delay">Postfix responds slowly to incoming SMTP connections</a>
 
@@ -141,7 +180,7 @@ domains with "relay access denied"</a>
 
 <ul>
 
-<li><a href="#dns-again">All remote mail stays queued with: Host not found, try again</a>
+<li><a href="#dns-again">Mail stays queued with: Host not found, try again</a>
 
 <li><a href="#timeouts">Mail fails consistently with timeout or lost connection</a>
 
@@ -157,6 +196,8 @@ domains with "relay access denied"</a>
 
 <li><a href="#biff">What does "biff_notify: Connection refused" mean?</a>
 
+<li><a href="#nisdom">What does "NIS domain name not set - NIS lookups disabled" mean?</a>
+
 <li><a href="#bogus">Postfix accepts mail for non-existing local users</a>
 
 <li><a href="#some_local">Delivering some users locally while
@@ -175,6 +216,8 @@ distribution list</a>
 
 <li><a href="#owner-foo">Postfix ignores the owner-list alias</a>
 
+<li><a href="#noalias">What does "fatal: open database /etc/aliases.db" mean?</a>
+
 </ul>
 
 <a name="mailing_lists"><h3>Mailing lists</h3>
@@ -270,10 +313,48 @@ mailbox</a>
 
 <hr>
 
+<a name="poppers"><h3>POP or IMAP problems</h3>
+
+Postfix is a mail delivery system. Postfix does not implement
+services such as POP or IMAP to read mail. Several POP/IMAP
+implementations exist that can cooperate with software such as
+Postfix.
+
+<p>
+
+Examples of software that is used successfully with Postfix:
+
+<p>
+
+<ul>
+
+<li><a href="http://asg.web.cmu.edu/cyrus/">Cyrus IMAP</a> implements
+IMAP, POP3, and KPOP, later versions also support TLS. This software
+implements its own private mail database system. Not for beginners.
+
+<p>
+
+<li><a href="http://www.inter7.com/courierimap/">Courier-Imap</a>
+provides POP3, IMAP, POP3 and IMAP, and supports access over SSL.
+This software supports the maildir-style mailbox format only
+(one message per file, same format as qmail).
+
+<p>
+
+<li><a href="http://www.eudora.com/qpopper/">Qpopper</a> supports 
+POP3, TLS (SSL), and uses the traditional UNIX-style mailbox format
+(multiple messages per file, each message starts with "From sender date...").
+
+</ul>
+
+<p>
+
+<hr>
+
 <a name="stand_alone"><h3>Stand-alone machine</h3>
 
 Out of the box, Postfix should work without change on a stand-alone
-machine that is has direct Internet access.  At least, that is how
+machine that has direct Internet access.  At least, that is how
 Postfix installs when you download the Postfix source code. If you
 are on a firewalled intranet, or if your machine is dial-up connected
 only a small part of the time, see the respective sections.
@@ -486,31 +567,39 @@ execute the command <b>postconf mail_version</b>.
 <p>
 
 How to set up Postfix on the firewall machine so that it relays
-mail for <i>my.domain</i> to a gateway machine on the inside, and
-so that it refuses mail for <i>*.my.domain</i>? The problem is that
-the standard <a href="uce.html#relay_domains">relay_domains</a>
-mail relaying restriction allows mail to <i>*.my.domain</i> when
-you specify <i>my.domain</i>.
+mail for <i>domain.com</i> to a gateway machine on the inside, and
+so that it refuses mail for <i>*.domain.com</i>? The problem is that
+the default <a href="uce.html#relay_domains">relay_domains</a>
+mail relaying restriction allows mail to <i>*.domain.com</i> when
+you specify <i>domain.com</i>.
 
 <p>
 
 <ul>
 
-<li>Specify a null <a href="uce.html#relay_domains">relay_domains</a>
-parameter plus a <a href="transport.5.html">transport</a> table to
-route mail for <i>my.domain</i> to the inside machine:
+<li>Specify a <a href="transport.5.html">transport</a> table to
+route mail for <i>domain.com</i> to the inside machine.
+
+<p>
+
+Specify explicit settings for <a
+href="uce.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a>
+and for <a href="basic.html#mynetworks">mynetworks</a> that allow
+local systems to send mail anywhere, and that allow remote systems
+to send mail only to <i>user@domain.com</i>.
 
 <p>
 
 <pre>
 /etc/postfix/main.cf:
-    mydestination = $myhostname, my.domain, localhost.my.domain
-    relay_domains =
+    myorigin = domain.com
+    mydestination = domain.com
     transport_maps = hash:/etc/postfix/transport
+    mynetworks = 12.34.56.0/24
+    smtpd_recipient_restrictions = permit_mynetworks reject_unauth_destination
 
 /etc/postfix/transport:
-    my.domain   smtp:inside-gateway.my.domain   (forwards user@domain)
-    .my.domain  smtp:inside-gateway.my.domain   (forwards user@firewall)
+    domain.com   smtp:inside-gateway.domain.com   (forwards user@domain)
 
 /etc/postfix/master.cf:
     Comment out the local delivery agent
@@ -806,7 +895,161 @@ delivery agent deals with undeliverable mail.
 
 <hr>
 
-<a name="incoming"><h3>Too much mail in the incoming queue</h3></a>
+<a name="noalias"><h3>What does "fatal: open database /etc/aliases.db" mean?</h3></a>
+
+Your aliases database is corrupt or it is missing. Execute the 
+following command as root:
+
+<p>
+
+<pre>
+    # newaliases
+</pre>
+
+<hr>
+
+<a name="nosuid"><h1>sendmail has set-uid root file permissions, or is run from a
+set-uid root process</h3></a>
+
+Traditionally, the UNIX <b>sendmail</b> command is installed with
+set-uid root permissions. Even many MTAs other than Sendmail ship
+with a set-uid root <b>sendmail</b> command. This is not the case
+with Postfix.  The Postfix <b>sendmail</b> command is designed not
+to be set-uid.
+
+<p>
+
+Unfortunately, some Linux systems have a helpful utility called
+<b>linuxconf</b> that automatically "fixes" file permissions to
+what they are supposed to be for Sendmail's <b>sendmail</b> command.
+Even when you reset the set-uid bit on the Postfix <b>sendmail</b>
+executable file, <b>linuxconf</b> will happily turn it on again
+for you.
+
+<p>
+
+On SuSE systems the file permission fixing utulity is called
+<b>SuSEconfig</b>.  Other Linux systems may use different names.
+The usual disclaimers about mileages etc. apply.
+
+<p>
+
+<h4>Solutions</h4>
+
+<ul>
+
+<li>Rask Ingemann Lambertsen has a particularly effective
+solution :-)
+
+<blockquote>
+<pre>
+# /etc/rc.d/init.d/linuxconf stop && rpm --erase linuxconf 
+</pre>
+</blockquote>
+
+<li>According to Matthias Andree, the band-aid fix for SuSE is to
+add to /etc/permissions.local the following line:
+
+<blockquote>
+<pre>
+/usr/sbin/sendmail root.root 755
+</pre>
+</blockquote>
+
+and to make sure that in /etc/rc.config,
+PERMISSIONS_SECURITY mentions local last, EXAMPLE:
+
+<blockquote>
+<pre>
+CHECK_PERMISSIONS=set
+PERMISSION_SECURITY="secure local"
+</pre>
+</blockquote>
+
+</ul>
+
+<hr>
+
+<a name="moby-freebsd"><h3>Running hundreds of Postfix processes on FreeBSD</h3></a>
+
+With hundreds of Postfix processes, the kernel will eventually
+run out of file handles; after that, it will run out of sockets.
+
+<p>
+
+To set kernel parameters at boot time, add the following lines to
+the <b>/boot/loader.conf</b> file (this is specific to FreeBSD 4.x):
+
+<p>
+
+<blockquote>
+<pre>
+kern.ipc.maxsockets="5000"
+kern.maxfiles="16384"
+kern.maxfilesperproc="16384"
+kern.ipc.nmbclusters="65536"
+</pre>
+</blockquote>
+
+<p>
+
+To set kernel parameters at run time execute the following commands
+as root (this is specific to FreeBSD 4.x):
+
+<p>
+
+<blockquote>
+<pre>
+# sysctl -w kern.ipc.maxsockets=5000
+# sysctl -w kern.maxfiles=16384
+# sysctl -w kern.maxfilesperproc=16384
+# sysctl -w kern.ipc.nmbclusters=65536
+</pre>
+</blockquote>
+
+<hr>
+
+<a name="moby-linux"><h3>Running hundreds of Postfix processes on Linux</h3></a>
+
+When you increase the number of Postfix processes into the hundreds,
+the kernel will eventually run out of file handles; after that it
+is likely to run out of process slots.
+
+<p>
+
+The following information is kernel version dependent.
+
+<p>
+
+To set parameters at boot time on Linux systems that have
+<b>/etc/sysctl.conf</b>, add the following lines:
+
+<p>
+
+<blockquote>
+<pre>
+fs.file-max = 16384
+kernel.threads-max = 2048
+</pre>
+</blockquote>
+
+<p>
+
+To set kernel parameters at run time, execute the following
+commands as <b>root</b>:
+
+<p>
+
+<blockquote>
+<pre>
+# echo 16384 > /proc/sys/fs/file-max
+# echo 2048 > /proc/sys/kernel/threads-max
+</pre>
+</blockquote>
+
+<hr>
+
+<a name="incoming"><h3>Mail stays queued in the incoming queue</h3></a>
 
 <blockquote>
 
@@ -829,14 +1072,16 @@ You solve the problem by getting faster disks.
 
 <p>
 
-I am still solving the scheduling problem from the software side.
+I am still solving the scheduling problem from the software side,
+but don't hold your breath.
 
 <p>
 
 Currently, the workaround is to configure multiple IP addresses
-per machine, and to run one Postfix instance per IP address.  The
-Postfix instances can't share queue directories, but sharing mailbox
-directories is OK.
+per machine, and to run one Postfix instance per IP address, each
+instance preferably on a different disk.  The Postfix instances
+can't share queue directories, but sharing mailbox directories is
+OK.
 
 <p>
 
@@ -857,9 +1102,10 @@ depending on the interface that it is supposed to handle.
 <p>
 
 <pre>
-    queue_directory = /my/own/queue/directory
-    myhostname = foo1.my.domain
-    inet_interfaces = $myhostname
+    /my/own/main.cf:
+       queue_directory = /my/own/queue/directory
+       myhostname = foo1.my.domain
+       inet_interfaces = $myhostname
 </pre>
 
 <hr>
@@ -1242,7 +1488,8 @@ host.
 
 <a name="backup"><h3>Configuring Postfix as backup MX host</h3></a>
 
-When you are SECONDARY MX for some other domain this is all you need:
+When you are <b>secondary mx</b> for a <b>remote site</b> this is
+all you need:
 
 <p>
 
@@ -1251,12 +1498,14 @@ When you are SECONDARY MX for some other domain this is all you need:
         the.backed-up.domain.name        IN      MX 100 your.machine.name
 
     /etc/postfix/main.cf:
-        relay_domains = the.backed-up.domain.name
+        relay_domains = $mydestination the.backed-up.domain.name
+       smtpd_recipient_restrictions = permit_mynetworks check_relay_domains
 </pre>
 
 <p>
 
-When you are PRIMARY MX for some other domain you also need:
+When you are <b>primary mx</b> for a <b>remote site</b> you also
+need:
 
 <p>
 
@@ -1276,11 +1525,11 @@ types Postfix supports, use the command <b>postconf -m</b>.
 
 <hr>
 
-<a name="dns-again"><h3>All remote mail stays queued with: Host not found, try again</h3></a>
+<a name="dns-again"><h3>Mail stays queued with: Host not found, try again</h3></a>
 
 <blockquote>
 
-When I connect send mail to a remote address, the following happens:
+When I send mail to a remote address, the following happens:
 
 <p>
 
@@ -1292,15 +1541,35 @@ When I connect send mail to a remote address, the following happens:
        service error for domain recip.domain: Host not found, try again)
 </pre>
 
+<p>
+
+However, I can nslookup the hostname just fine.
+
 </blockquote>
 
 <p>
 
+There can be several different problems.
+
+<p>
+
+<ul>
+
+<li> First of all, the result of nslookup for the hostname may be
+irrelevant. Postfix is required to look up the MX record first. So
+your nslookup test should begin with asking for the MX record. Some
+DNS servers are broken and produce no reply when asked for a
+non-existent MX record.
+
+<p> <li>
+
 Check out your Postfix <b>master.cf</b> file. If the SMTP client
 runs chrooted, then it needs a bunch of files inside the Postfix
 queue directory.  Examples are in the source distribution in the
 <b>examples</b> subdirectory.
 
+</ul>
+
 <hr>
 
 <a name="timeouts"><h3>Mail fails consistently with timeout or lost connection</h3></a>
@@ -1314,10 +1583,40 @@ by itself.
 <p>
 
 However, when you see mail deliveries fail consistently, you may
-have a different problem: broken path MTU discovery.
+have a different problem: broken path MTU discovery. Or it could
+be a broken PIX firewall.
+
+<h4>Cisco PIX "fixup protocol smtp" bug</h4>
+
+The Cisco PIX firewall has a bug when running software older than
+version 5.2(4) or 6.0(1).
+
+<p>
+
+The bug ID is CSCds90792. The "fixup protocol smtp" feature does
+not correctly handle the case where the "." and the "CRLF" at the
+end of mail are sent in separate packets.
+
+<p>
+
+How does one recognize a mailer behind a Cisco PIX with "fixup
+protocol smtp" enabled? As of version 5.1 and later, the fixup
+protocol smtp command changes the characters in the SMTP banner to
+asterisks except for the "2", "0" and "0 SPACE" characters. 
 
 <p>
 
+When you connect to a mailer behind such a filter you see something
+like:
+
+<blockquote>
+<pre>
+220 **************************************0******0*********20 ****200**0*********0*00
+</pre>
+</blockquote>
+
+<h4>IP path MTU discovery</h4>
+
 A little background is in order. With the SMTP protocol, the HELO,
 MAIL FROM and RCPT TO commands and responses are relatively short.
 When you're talking to sendmail, every command and every response
@@ -1506,7 +1805,36 @@ specify:
 <p>
 
 To enable the <b>comsat</b> network service, uncomment the
-corresponding entry in the <b>inetd.conf</b> file.
+corresponding entry in the <b>inetd.conf</b> file, and <b>kill -HUP</b>
+the <b>inetd</b> process.
+
+<hr>
+
+<a name="nisdom"><h3>What does "NIS domain name not set - NIS lookups disabled" mean?</h3>
+
+<p>
+
+The warning message means that NIS (Network Information Service)
+is not enabled on your machine.  That is perfectly OK. It's just
+hard for Postfix to find out about these things ahead of time.
+
+<p>
+
+To disable the <b>NIS</b> client code in the Postfix local delivery agent,
+update the corresponding section in the <b>main.cf</b> file and specify
+one of the following, depending on the type of aliases file:
+
+<p>
+
+<pre>
+/etc/postfix/main.cf:
+    alias_maps = $alias_database
+</pre>
+
+<p>
+
+This forces Postfix to use only the local aliases database, if one
+is defined.
 
 <hr>
 
@@ -2368,7 +2696,7 @@ with Postfix and HylaFax. Here's the setup used:
 
 <pre>
     /etc/postfix/master.cf:
-        fax       unix  -       n       n       -       -       pipe
+        fax       unix  -       n       n       -       1       pipe
             flags= user=fax argv=/usr/bin/faxmail -d -n ${user}
 
     /etc/postfix/transport:
@@ -2381,6 +2709,12 @@ with Postfix and HylaFax. Here's the setup used:
 
 <p>
 
+The process limit of 1 in the <b>master.cf</b> file is necessary
+with fax software that cannot handle multiple requests at the same
+time. It won't hurt otherwise.
+
+<p>
+
 The <b>fax_destination_recipient_limit</b> entry (by Simon, Mr.
 Simix) is necessary with fax software that can't have more than
 one destination on its command line. It won't hurt otherwise.
@@ -2393,14 +2727,14 @@ types Postfix supports, use the command <b>postconf -m</b>.
 
 <p>
 
-Note: be sure to not advertise <b>fax.your.domain</b> in the DNS...
+Note: be sure to not advertise <b>fax.your.domain</b> in the DNS :-)
 
 <hr>
 
 <a name="deleting"><h3>Deleting a message from the Postfix queue</h3></a>
 
-To delete ONE message with queue id ABCDEF from the Postfix queue,
-it is not necessary to stop Postfix.
+To delete ONE message with queue id ABCDEF (e.g., from <b>mailq</b>
+output) from the Postfix queue, it is not necessary to stop Postfix.
 
 <p>
 
@@ -2417,8 +2751,8 @@ the same queue file name.
 
 <p>
 
-If you have to delete a large amount of mail, it is safer to stop
-Postfix first.
+If you have to delete a large amount of mail, you must stop Postfix
+first.
 
 <p>
 <pre>
@@ -2431,9 +2765,9 @@ Postfix first.
 
 <p>
 
-Do not use the above command on a running Postfix system, because
-it can delete files that belong to new mail that arrives while you
-are deleting queue files.
+Do not use the above <b>find</b> command on a running Postfix
+system, because it can delete files that belong to new mail that
+arrives while you are deleting queue files.
 
 <hr>
 
index 5cacb4f3792bf434c0c66fde5645c67c90219f01..32b4627ae33b4d65fda4e756ccacfcbee39473fa 100644 (file)
@@ -29,17 +29,15 @@ First of all, thank you for your interest in the Postfix project.
 <p>
 
 What is Postfix? It is <a href="http://www.porcupine.org/wietse/">Wietse
-Venema's</a> attempt to provide an alternative to the widely-used
-<a href="http://www.sendmail.org/">Sendmail</a> program.  Sendmail
-is responsible for most of the e-mail delivered on the Internet.
-With an estimated 100 million users, that's billions of messages
-daily.  A stunning number.
+Venema's</a> mailer that started life as an alternative to the
+widely-used <a href="http://www.sendmail.org/">Sendmail</a> program.
 
 <p>
 
 Postfix attempts to be fast, easy to administer, and secure, while
 at the same time being sendmail compatible enough to not upset
-existing users.
+existing users. Thus, the outside has a sendmail-ish flavor, but    
+the inside is completely different.
 
 <hr>
 
index 25ff4baf0f4a7f3b9db522c5583dab2f7bae4189..653d5d8e40c5ee3611107b4edde55dd9d5c85930 100644 (file)
@@ -29,21 +29,22 @@ LMTP(8)                                                   LMTP(8)
        specified in the Postfix <a href="transport.5.html"><b>transport</b>(5)</a> table, has the form:
 
        <b>unix</b>:<i>pathname</i>
-              Connect to the UNIX-domain server that is bound  to
-              the   specified   <i>pathname</i>.  If  the  process  runs
-              chrooted, an absolute pathname is interpreted rela-
-              tive to the changed root directory.
+              Connect to the local  UNIX-domain  server  that  is
+              bound  to  the  specified  <i>pathname</i>. If the process
+              runs chrooted, an absolute pathname is  interpreted
+              relative to the changed root directory.
 
        <b>inet</b>:<i>host</i>, <b>inet:</b><i>host</i>:<i>port</i> (symbolic host)
 
        <b>inet</b>:[<i>addr</i>], <b>inet</b>:[<i>addr</i>]:<i>port</i> (numeric host)
               Connect to the specified IPV4 TCP port on the spec-
-              ified host. If no port is specified, connect to the
-              port  defined  as  <b>lmtp</b> in <b>services</b>(4).  If no such
-              service is found, the  <b>lmtp</b><i>_</i><b>tcp</b><i>_</i><b>port</b>  configuration
-              parameter (default value of 24) will be used.
+              ified local or remote host. If no  port  is  speci-
+              fied,  connect  to the port defined as <b>lmtp</b> in <b>ser-</b>
+              <b>vices</b>(4).   If  no  such  service  is  found,   the
+              <b>lmtp</b><i>_</i><b>tcp</b><i>_</i><b>port</b>   configuration   parameter  (default
+              value of 24) will be used.
 
-              The   LMTP   client   does  not  perform  MX  (mail
+              The  LMTP  client  does  not   perform   MX   (mail
               exchanger) lookups since those are defined only for
               mail delivery via SMTP.
 
@@ -52,13 +53,12 @@ LMTP(8)                                                   LMTP(8)
 
 <b>SECURITY</b>
        The LMTP client is moderately security-sensitive. It talks
-       to  LMTP  servers  and  to DNS servers on the network. The
+       to LMTP servers and to DNS servers  on  the  network.  The
        LMTP client can be run chrooted at fixed low privilege.
 
 <b>STANDARDS</b>
        <a href="http://www.faqs.org/rfcs/rfc821.html">RFC 821</a> (SMTP protocol)
        <a href="http://www.faqs.org/rfcs/rfc1651.html">RFC 1651</a> (SMTP service extensions)
-       <a href="http://www.faqs.org/rfcs/rfc1870.html">RFC 1870</a> (Message Size Declaration)
 
 
 
@@ -71,60 +71,60 @@ LMTP(8)                                                   LMTP(8)
 LMTP(8)                                                   LMTP(8)
 
 
+       <a href="http://www.faqs.org/rfcs/rfc1870.html">RFC 1870</a> (Message Size Declaration)
        <a href="http://www.faqs.org/rfcs/rfc2033.html">RFC 2033</a> (LMTP protocol)
        <a href="http://www.faqs.org/rfcs/rfc2197.html">RFC 2197</a> (Pipelining)
+       <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a> (AUTH command)
 
 <b>DIAGNOSTICS</b>
-       Problems and transactions are logged to <b>syslogd</b>(8).   Cor-
-       rupted  message files are marked so that the queue manager
+       Problems  and transactions are logged to <b>syslogd</b>(8).  Cor-
+       rupted message files are marked so that the queue  manager
        can move them to the <b>corrupt</b> queue for further inspection.
 
-       Depending  on the setting of the <b>notify</b><i>_</i><b>classes</b> parameter,
-       the postmaster is notified of bounces, protocol  problems,
+       Depending on the setting of the <b>notify</b><i>_</i><b>classes</b>  parameter,
+       the  postmaster is notified of bounces, protocol problems,
        and of other trouble.
 
 <b>BUGS</b>
 <b>CONFIGURATION</b> <b>PARAMETERS</b>
-       The  following  <b>main.cf</b> parameters are especially relevant
-       to this program. See the Postfix <b>main.cf</b> file  for  syntax
-       details  and  for  default  values. Use the <b>postfix</b> <b>reload</b>
+       The following <b>main.cf</b> parameters are  especially  relevant
+       to  this  program. See the Postfix <b>main.cf</b> file for syntax
+       details and for default values.  Use  the  <b>postfix</b>  <b>reload</b>
        command after a configuration change.
 
 <b>Miscellaneous</b>
        <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
-              Verbose logging  level  increment  for  hosts  that
+              Verbose  logging  level  increment  for  hosts that
               match a pattern in the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b> parameter.
 
        <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
-              List  of  domain or network patterns. When a remote
-              host matches a pattern, increase the  verbose  log-
-              ging   level   by   the  amount  specified  in  the
+              List of domain or network patterns. When  a  remote
+              host  matches  a pattern, increase the verbose log-
+              ging  level  by  the  amount   specified   in   the
               <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> parameter.
 
        <b>error</b><i>_</i><b>notice</b><i>_</i><b>recipient</b>
-              Recipient   of    protocol/policy/resource/software
+              Recipient    of   protocol/policy/resource/software
               error notices.
 
        <b>notify</b><i>_</i><b>classes</b>
-              When  this  parameter  includes the <b>protocol</b> class,
-              send mail to the  postmaster  with  transcripts  of
+              When this parameter includes  the  <b>protocol</b>  class,
+              send  mail  to  the  postmaster with transcripts of
               LMTP sessions with protocol errors.
 
        <b>lmtp</b><i>_</i><b>skip</b><i>_</i><b>quit</b><i>_</i><b>response</b>
-              Do  not  wait for the server response after sending
+              Do not wait for the server response  after  sending
               QUIT.
 
        <b>lmtp</b><i>_</i><b>tcp</b><i>_</i><b>port</b>
-              The TCP port to be used when connecting to  a  LMTP
-              server.   Used as backup if the <b>lmtp</b> service is not
+              The  TCP  port to be used when connecting to a LMTP
+              server.  Used as backup if the <b>lmtp</b> service is  not
               found in <b>services</b>(4).
 
-<b>Resource</b> <b>controls</b>
-       <b>lmtp</b><i>_</i><b>cache</b><i>_</i><b>connection</b>
-              Should we cache the connection to the LMTP  server?
-              The  effectiveness  of  cached  connections will be
-              determined by the number of LMTP  servers  in  use,
-              and  the  concurrency  limit specified for the LMTP
+<b>Authentication</b> <b>controls</b>
+       <b>lmtp</b><i>_</i><b>enable</b><i>_</i><b>sasl</b><i>_</i><b>auth</b>
+              Enable  per-session  authentication as per <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a>
+              (SASL).  By default, Postfix is built without  SASL
 
 
 
@@ -137,108 +137,153 @@ LMTP(8)                                                   LMTP(8)
 LMTP(8)                                                   LMTP(8)
 
 
+              support.
+
+       <b>lmtp</b><i>_</i><b>sasl</b><i>_</i><b>password</b><i>_</i><b>maps</b>
+              Lookup tables with per-host or domain <i>name</i>:<i>password</i>
+              entries.  No entry for a host means no  attempt  to
+              authenticate.
+
+       <b>lmtp</b><i>_</i><b>sasl</b><i>_</i><b>security</b><i>_</i><b>options</b>
+              Zero or more of the following.
+
+              <b>noplaintext</b>
+                     Disallow  authentication  methods  that  use
+                     plaintext passwords.
+
+              <b>noactive</b>
+                     Disallow  authentication  methods  that  are
+                     vulnerable to non-dictionary active attacks.
+
+              <b>nodictionary</b>
+                     Disallow  authentication  methods  that  are
+                     vulnerable to passive dictionary attack.
+
+              <b>noanonymous</b>
+                     Disallow anonymous logins.
+
+<b>Resource</b> <b>controls</b>
+       <b>lmtp</b><i>_</i><b>cache</b><i>_</i><b>connection</b>
+              Should  we cache the connection to the LMTP server?
+              The effectiveness of  cached  connections  will  be
+              determined  by  the  number of LMTP servers in use,
+              and the concurrency limit specified  for  the  LMTP
               client.  Cached connections are closed under any of
               the following conditions:
 
-              <b>o</b>      The  LMTP client idle time limit is reached.
-                     This limit is  specified  with  the  Postfix
+              <b>o</b>      The LMTP client idle time limit is  reached.
+                     This  limit  is  specified  with the Postfix
                      <b>max</b><i>_</i><b>idle</b> configuration parameter.
 
-              <b>o</b>      A  delivery  request  specifies  a different
+              <b>o</b>      A delivery  request  specifies  a  different
                      destination than the one currently cached.
 
               <b>o</b>      The  per-process  limit  on  the  number  of
                      delivery requests is reached.  This limit is
-                     specified with the Postfix <b>max</b><i>_</i><b>use</b>  configu-
+                     specified  with the Postfix <b>max</b><i>_</i><b>use</b> configu-
                      ration parameter.
 
-              <b>o</b>      Upon  the onset of another delivery request,
-                     the LMTP server associated with the  current
-                     session  does  not  respond to the <b>RSET</b> com-
+              <b>o</b>      Upon the onset of another delivery  request,
+                     the  LMTP server associated with the current
+                     session does not respond to  the  <b>RSET</b>  com-
                      mand.
 
        <i>transport_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
               Limit the number of parallel deliveries to the same
-              destination   via  this  mail  delivery  transport.
-              <i>transport</i> is the name of the service  as  specified
-              in  the <b>master.cf</b> file.  The default limit is taken
-              from   the    <b>default</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
+              destination  via  this  mail  delivery   transport.
+
+
+
+                                                                3
+
+
+
+
+
+LMTP(8)                                                   LMTP(8)
+
+
+              <i>transport</i>  is  the name of the service as specified
+              in the <b>master.cf</b> file.  The default limit is  taken
+              from    the   <b>default</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
               parameter.
 
        <i>transport_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
               Limit the number of recipients per message delivery
-              via this mail delivery transport. <i>transport</i> is  the
-              name  of  the service as specified in the <b>master.cf</b>
-              file.   The  default  limit  is  taken   from   the
+              via  this mail delivery transport. <i>transport</i> is the
+              name of the service as specified in  the  <b>master.cf</b>
+              file.    The   default  limit  is  taken  from  the
               <b>default</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b> parameter.
 
-              This  parameter  becomes  significant  if  the LMTP
-              client is  used  for  local  delivery.   Some  LMTP
-              servers  can  optimize delivery of the same message
+              This parameter  becomes  significant  if  the  LMTP
+              client  is  used  for  local  delivery.   Some LMTP
+              servers can optimize delivery of the  same  message
               to multiple recipients. The default limit for local
               mail delivery is 1.
 
               Setting  this  parameter  to  0  will  lead  to  an
-              unbounded number of recipients per delivery.   How-
-              ever,  this  could  be  risky since it may make the
-              machine vulnerable to running out of  resources  if
-              messages  are encountered with an inordinate number
-              of recipients.  Exercise  care  when  setting  this
+              unbounded  number of recipients per delivery.  How-
+              ever, this could be risky since  it  may  make  the
+              machine  vulnerable  to running out of resources if
+              messages are encountered with an inordinate  number
+              of  recipients.   Exercise  care  when setting this
               parameter.
 
 <b>Timeout</b> <b>controls</b>
-       The  default  time  unit is seconds; an explicit time unit
-       can be specified by appending a one-letter suffix  to  the
-       value:  s (seconds), m (minutes), h (hours), d (days) or w
+       The default time unit is seconds; an  explicit  time  unit
+       can  be  specified by appending a one-letter suffix to the
+       value: s (seconds), m (minutes), h (hours), d (days) or  w
        (weeks).
 
-
-
-                                                                3
-
-
-
-
-
-LMTP(8)                                                   LMTP(8)
-
-
        <b>lmtp</b><i>_</i><b>connect</b><i>_</i><b>timeout</b>
               Timeout  for  opening  a  connection  to  the  LMTP
-              server.   If  no  connection can be made within the
+              server.  If no connection can be  made  within  the
               deadline, the message is deferred.
 
        <b>lmtp</b><i>_</i><b>lhlo</b><i>_</i><b>timeout</b>
-              Timeout for  sending  the  <b>LHLO</b>  command,  and  for
+              Timeout  for  sending  the  <b>LHLO</b>  command,  and for
               receiving the server response.
 
        <b>lmtp</b><i>_</i><b>mail</b><i>_</i><b>timeout</b>
-              Timeout  for sending the <b>MAIL</b> <b>FROM</b> command, and for
+              Timeout for sending the <b>MAIL</b> <b>FROM</b> command, and  for
               receiving the server response.
 
        <b>lmtp</b><i>_</i><b>rcpt</b><i>_</i><b>timeout</b>
-              Timeout for sending the <b>RCPT</b> <b>TO</b>  command,  and  for
+              Timeout  for  sending  the <b>RCPT</b> <b>TO</b> command, and for
               receiving the server response.
 
        <b>lmtp</b><i>_</i><b>data</b><i>_</i><b>init</b><i>_</i><b>timeout</b>
-              Timeout  for  sending  the  <b>DATA</b>  command,  and for
+              Timeout for  sending  the  <b>DATA</b>  command,  and  for
               receiving the server response.
 
+
+
+
+
+                                                                4
+
+
+
+
+
+LMTP(8)                                                   LMTP(8)
+
+
        <b>lmtp</b><i>_</i><b>data</b><i>_</i><b>xfer</b><i>_</i><b>timeout</b>
               Timeout for sending the message content.
 
        <b>lmtp</b><i>_</i><b>data</b><i>_</i><b>done</b><i>_</i><b>timeout</b>
               Timeout  for  sending  the  "<b>.</b>"  command,  and  for
-              receiving  the server response. When no response is
-              received, a warning is logged that the mail may  be
+              receiving the server response. When no response  is
+              received,  a warning is logged that the mail may be
               delivered multiple times.
 
        <b>lmtp</b><i>_</i><b>rset</b><i>_</i><b>timeout</b>
-              Timeout  for  sending  the  <b>RSET</b>  command,  and for
+              Timeout for  sending  the  <b>RSET</b>  command,  and  for
               receiving the server response.
 
        <b>lmtp</b><i>_</i><b>quit</b><i>_</i><b>timeout</b>
-              Timeout for  sending  the  <b>QUIT</b>  command,  and  for
+              Timeout  for  sending  the  <b>QUIT</b>  command,  and for
               receiving the server response.
 
 <b>SEE</b> <b>ALSO</b>
@@ -251,24 +296,12 @@ LMTP(8)                                                   LMTP(8)
        syslogd(8) system logging
 
 <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>
        Wietse Venema
        IBM T.J. Watson Research
-
-
-
-                                                                4
-
-
-
-
-
-LMTP(8)                                                   LMTP(8)
-
-
        P.O. Box 704
        Yorktown Heights, NY 10598, USA
 
@@ -293,39 +326,6 @@ LMTP(8)                                                   LMTP(8)
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
                                                                 5
 
 
index d9a39e7851dc3fd367d17fe1fa94a408408c13e5..e909eaa28480086e873cc7b6d221598a944d4df6 100644 (file)
@@ -16,8 +16,8 @@ LOCAL(8)                                                 LOCAL(8)
        Postfix queue manager to deliver mail to local recipients.
        Each  delivery  request  specifies  a queue file, a sender
        address, a domain or host to deliver to, and one  or  more
-       recipients.   This program expects to be run from the <a href="master.8.html"><b>mas-</b>
-       <b>ter</b>(8)</a> process manager.
+       recipients.   This program expects to be run from the <a href="master.8.html"><b>mas-</b></a>
+       <a href="master.8.html"><b>ter</b>(8)</a> process manager.
 
        The <b>local</b> daemon updates queue files and marks  recipients
        as finished, or it informs the queue manager that delivery
@@ -360,9 +360,10 @@ LOCAL(8)                                                 LOCAL(8)
        <b>recipient</b><i>_</i><b>delimiter</b>
               Separator between username and address extension.
 
-       <b>test</b><i>_</i><b>home</b><i>_</i><b>directory</b>
+       <b>require</b><i>_</i><b>home</b><i>_</i><b>directory</b>
               Require that a recipient's home directory is acces-
               sible by the recipient before attempting  delivery.
+              Defer delivery otherwise.
 
 <b>Mailbox</b> <b>delivery</b>
        <b>fallback</b><i>_</i><b>transport</b>
@@ -388,7 +389,6 @@ LOCAL(8)                                                 LOCAL(8)
               External command to use for mailbox  delivery.  The
               command  executes  with  the  recipient  privileges
               (exception: root). The string is subject  to  $name
-              expansions.
 
 
 
@@ -401,6 +401,8 @@ LOCAL(8)                                                 LOCAL(8)
 LOCAL(8)                                                 LOCAL(8)
 
 
+              expansions.
+
        <b>mailbox</b><i>_</i><b>transport</b>
               Message  transport  to  use for mailbox delivery to
               all local recipients, whether or not they are found
@@ -420,7 +422,7 @@ LOCAL(8)                                                 LOCAL(8)
        <b>stale</b><i>_</i><b>lock</b><i>_</i><b>time</b>
               Limit the time after which a stale lock is removed.
 
-       <b>mailbox</b><i>__</i><b>delivery</b><i>_</i><b>lock</b>
+       <b>mailbox</b><i>_</i><b>delivery</b><i>_</i><b>lock</b>
               What file locking method(s) to use when  delivering
               to  a  UNIX-style  mailbox.  The default setting is
               system dependent.  For a  list  of  available  file
@@ -449,12 +451,10 @@ LOCAL(8)                                                 LOCAL(8)
               ery.    The   default   limit  is  taken  from  the
               <b>default</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b> parameter.
 
-<b>Security</b> <b>controls</b>
-       <b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>commands</b>
-              Restrict the usage of  mail  delivery  to  external
-              command.
-
-
+       <b>mailbox</b><i>_</i><b>size</b><i>_</i><b>limit</b>
+              Limit the size of a mailbox  etc.  file  (any  file
+              that  is written to upon delivery).  Set to zero to
+              disable the limit.
 
 
 
@@ -467,9 +467,16 @@ LOCAL(8)                                                 LOCAL(8)
 LOCAL(8)                                                 LOCAL(8)
 
 
+<b>Security</b> <b>controls</b>
+       <b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>commands</b>
+              Restrict the usage of  mail  delivery  to  external
+              command.   Specify zero or more of: <b>alias</b>, <b>forward</b>,
+              <b>include</b>.
+
        <b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>files</b>
-              Restrict  the  usage  of  mail delivery to external
-              file.
+              Restrict the usage of  mail  delivery  to  external
+              file.   Specify  zero  or  more of: <b>alias</b>, <b>forward</b>,
+              <b>include</b>.
 
        <b>command</b><i>_</i><b>expansion</b><i>_</i><b>filter</b>
               What characters are  allowed  to  appear  in  $name
@@ -517,13 +524,6 @@ LOCAL(8)                                                 LOCAL(8)
 
 
 
-
-
-
-
-
-
-
                                                                 8
 
 
index b9f3b7963dfd0e6aefe78b13d56ea8ee92ab3b50..372b037a3922d0424f4c3975379c1e45c2fc7a93 100644 (file)
@@ -19,8 +19,8 @@ POSTDROP(1)                                           POSTDROP(1)
        and  with  group  write  permission  to the <b>maildrop</b> queue
        directory.
 
-       The <b>postdrop</b> command is automatically invoked by the <a href="sendmail.1.html"><b>send-</b>
-       <b>mail</b>(1)</a>  mail posting agent when the <b>maildrop</b> queue direc-
+       The <b>postdrop</b> command is automatically invoked by the <a href="sendmail.1.html"><b>send-</b></a>
+       <a href="sendmail.1.html"><b>mail</b>(1)</a>  mail posting agent when the <b>maildrop</b> queue direc-
        tory is not world-writable.
 
        Options:
index 213a35b04f6f64281f755bbc9f39bd093d07d816..032e6dfdbc6857f519dd7f8b7be1308c95ee5a23 100644 (file)
@@ -14,8 +14,8 @@ QMGR(8)                                                   QMGR(8)
 <b>DESCRIPTION</b>
        The  <b>qmgr</b>  daemon  awaits the arrival of incoming mail and
        arranges for its delivery via Postfix delivery  processes.
-       The actual mail routing strategy is delegated to the <a href="trivial-rewrite.8.html"><b>triv-</b>
-       <b>ial-rewrite</b>(8)</a> daemon.  This program  expects  to  be  run
+       The actual mail routing strategy is delegated to the <a href="trivial-rewrite.8.html"><b>triv-</b></a>
+       <a href="trivial-rewrite.8.html"><b>ial-rewrite</b>(8)</a> daemon.  This program  expects  to  be  run
        from the <a href="master.8.html"><b>master</b>(8)</a> process manager.
 
        Mail  addressed  to  the  local  <b>double-bounce</b>  address is
index a6fe58de545e39a604780385f2ae162a988611ef..97ae6d8377baa8d3882d30272d4eb71fbbc0839c 100644 (file)
@@ -77,7 +77,7 @@ SMTPD(8)                                                 SMTPD(8)
               For  example, allow <a href="http://www.faqs.org/rfcs/rfc822.html">RFC822</a>-style address forms with
               comments, like Sendmail does.
 
-       <b>allow</b><i>_</i><b>broken</b><i>_</i><b>auth</b><i>_</i><b>clients</b>
+       <b>broken</b><i>_</i><b>sasl</b><i>_</i><b>auth</b><i>_</i><b>clients</b>
               Support older Microsoft clients that  mis-implement
               the AUTH protocol, and that expect an EHLO response
               of "250 AUTH=list" instead of "250 AUTH list".
@@ -90,13 +90,16 @@ SMTPD(8)                                                 SMTPD(8)
               same  syntax  as  the  right-hand side of a Postfix
               transport table.
 
-<b>Authenication</b> <b>controls</b>
+<b>Authentication</b> <b>controls</b>
        <b>enable</b><i>_</i><b>sasl</b><i>_</i><b>authentication</b>
               Enable per-session authentication as per  <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC  2554</a>
               (SASL).   This functionality is available only when
               explicitly  selected  at  program  build  time  and
               explicitly enabled at runtime.
 
+       <b>smtpd</b><i>_</i><b>sasl</b><i>_</i><b>local</b><i>_</i><b>domain</b>
+              The name of the local authentication realm.
+
        <b>smtpd</b><i>_</i><b>sasl</b><i>_</i><b>security</b><i>_</i><b>options</b>
               Zero or more of the following.
 
@@ -122,9 +125,6 @@ SMTPD(8)                                                 SMTPD(8)
 
        <b>command</b><i>_</i><b>directory</b>
               Location  of  Postfix  support  commands  (default:
-              <b>$program</b><i>_</i><b>directory</b>).
-
-
 
 
 
@@ -137,6 +137,8 @@ SMTPD(8)                                                 SMTPD(8)
 SMTPD(8)                                                 SMTPD(8)
 
 
+              <b>$program</b><i>_</i><b>directory</b>).
+
        <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
               Increment  in  verbose  logging level when a remote
               host  matches  a  pattern  in  the  <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
@@ -189,8 +191,6 @@ SMTPD(8)                                                 SMTPD(8)
        <b>soft</b><i>_</i><b>bounce</b>
               Change hard (5xx) reject responses into soft  (4xx)
               reject  responses.   This can be useful for testing
-              purposes.
-
 
 
 
@@ -203,6 +203,8 @@ SMTPD(8)                                                 SMTPD(8)
 SMTPD(8)                                                 SMTPD(8)
 
 
+              purposes.
+
 <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
@@ -254,9 +256,7 @@ SMTPD(8)                                                 SMTPD(8)
               Restrict what sender addresses are allowed in  <b>MAIL</b>
               <b>FROM</b> commands.
 
-       <b>smtpd</b><i>_</i><b>recipient</b><i>_</i><b>restrictions</b>
-              Restrict  what  recipient  addresses are allowed in
-              <b>RCPT</b> <b>TO</b> commands.
+
 
 
 
@@ -269,6 +269,10 @@ SMTPD(8)                                                 SMTPD(8)
 SMTPD(8)                                                 SMTPD(8)
 
 
+       <b>smtpd</b><i>_</i><b>recipient</b><i>_</i><b>restrictions</b>
+              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.
@@ -318,10 +322,6 @@ SMTPD(8)                                                 SMTPD(8)
               Server  response  when  a   client   violates   the
               <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>address</b> restriction.
 
-       <b>unknown</b><i>_</i><b>client</b><i>_</i><b>reject</b><i>_</i><b>code</b>
-              Server  response  when  a client without address to
-              name mapping  violates  the  <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>clients</b>
-              restriction.
 
 
 
@@ -335,6 +335,11 @@ SMTPD(8)                                                 SMTPD(8)
 SMTPD(8)                                                 SMTPD(8)
 
 
+       <b>unknown</b><i>_</i><b>client</b><i>_</i><b>reject</b><i>_</i><b>code</b>
+              Server  response  when  a client without address to
+              name mapping  violates  the  <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>clients</b>
+              restriction.
+
        <b>unknown</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
               Server   response   when   a  client  violates  the
               <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>hostname</b> restriction.
@@ -381,11 +386,6 @@ SMTPD(8)                                                 SMTPD(8)
 
 
 
-
-
-
-
-
 
 
 
index ce97479f810ff20b57345162d3aa40598dc13ab2..f24125814790db4c5b98216e32d387fcda2b2aac 100644 (file)
@@ -43,8 +43,8 @@ TRIVIAL-REWRITE(8)                             TRIVIAL-REWRITE(8)
 
               The  <b>trivial-rewrite</b> daemon by default only distin-
               guishes between local and non-local mail. For finer
-              control  over mail routing, use the optional <a href="transport.5.html"><b>trans-</b>
-              <b>port</b>(5)</a> lookup table.
+              control  over mail routing, use the optional <a href="transport.5.html"><b>trans-</b></a>
+              <a href="transport.5.html"><b>port</b>(5)</a> lookup table.
 
        This program expects to be run from the <a href="master.8.html"><b>master</b>(8)</a>  process
        manager.
index d35330a2f104c41dddcf100d282e9eea20ea1c20..6333a381cfa95718a7bb31d752c56bd033a5a430 100644 (file)
@@ -109,7 +109,8 @@ is allowed in message headers.
 <dt>Syntax:
 
 <dd>Specify a list of zero or more lookup tables. Whenever a header
-matches a table, a REJECT result means reject the message. 
+matches a table, a REJECT result means reject the message, and a 
+SKIP result means delete the header from the message.
 
 <p>
 
@@ -979,7 +980,7 @@ appear as part of a client hostname/address restriction list.
 
 <dt>Default:
 
-<dd><b>maps_rbl_domains = rbl.maps.vix.com, dul.maps.vix.com</b>
+<dd><b>maps_rbl_domains = blackholes.mail-abuse.org</b>
 
 <p>
 
index d0cea5588e6f7c04b2344118173e5004e91fda94..2f110f03fdb0eb7f4b95c5b70d0575d52a183dfe 100644 (file)
@@ -218,7 +218,7 @@ ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543
                RANLIB=echo
                SYSLIBS="-lresolv -lsocket -lnsl"
                ;;
-Rhapsody.5*|Darwin.1.2*)
+Rhapsody.5*|Darwin.1.*)
                SYSTYPE=RHAPSODY5
                # Use the native compiler by default
                : ${CC=cc}
index 70b4d98176974450515e6acbaeac454b451bd2ad..21b58261c5b68dc847e15fe948ebfd211d220a8d 100644 (file)
@@ -5,7 +5,7 @@ SHELL   = /bin/sh
 DAEMONS        = man8/bounce.8 man8/defer.8 man8/cleanup.8 man8/error.8 man8/local.8 \
        man8/lmtp.8 man8/master.8 man8/pickup.8 man8/pipe.8 man8/qmgr.8 \
        man8/showq.8 man8/smtp.8 man8/smtpd.8 man8/trivial-rewrite.8 \
-       man8/spawn.8 man8/flush.8 
+       man8/spawn.8 man8/flush.8 # man8/nqmgr.8 man8/virtual.8
 COMMANDS= man1/postalias.1 man1/postcat.1 man1/postconf.1 man1/postfix.1 \
        man1/postkick.1 man1/postlock.1 man1/postlog.1 man1/postdrop.1 \
        man1/postmap.1 man1/sendmail.1 man1/mailq.1 man1/newaliases.1 \
@@ -50,6 +50,12 @@ man8/lmtp.8: ../src/lmtp/lmtp.c
 man8/master.8: ../src/master/master.c
        ../mantools/srctoman $? >$@
 
+man8/nqmgr.8: ../src/nqmgr/qmgr.c
+       ../mantools/srctoman $? | \
+               sed -e 's/qmgr[^_]/n&/' \
+                   -e 's/qmgr$$/n&/' \
+                   -e 's/QMGR[^_]/N&/' >$@
+
 man8/pickup.8: ../src/pickup/pickup.c
        ../mantools/srctoman $? >$@
 
@@ -71,6 +77,9 @@ man8/smtp.8: ../src/smtp/smtp.c
 man8/smtpd.8: ../src/smtpd/smtpd.c
        ../mantools/srctoman $? >$@
 
+man8/virtual.8: ../src/virtual/virtual.c
+       ../mantools/srctoman $? >$@
+
 man8/trivial-rewrite.8: ../src/trivial-rewrite/trivial-rewrite.c
        ../mantools/srctoman $? >$@
 
index 39a376ecde7ce18a82f6e76966baeb2c463a92e0..851a1390fac4f560581755796405423d99bce3d8 100644 (file)
@@ -76,8 +76,10 @@ the numerical code and text.
 Reject the address etc. that matches the pattern. A generic
 error response message is generated.
 .IP \fBOK\fR
-.IP "\fIAny other text\fR"
 Accept the address etc. that matches the pattern.
+.IP \fIrestriction...\fR
+Apply the named UCE restriction (\fBpermit\fR, \fRreject\fR,
+\fBreject_unauth_destination\fR, and so on).
 .SH REGULAR EXPRESSION TABLES
 .na
 .nf
index 3fe89ed124e5ce06f738e95888ad72cfa72ce193..0521d53e5b54b34a132824a020e827856a797b7d 100644 (file)
@@ -27,14 +27,14 @@ The LMTP client connects to the destination specified in the message
 delivery request. The destination, usually specified in the Postfix
 \fBtransport\fR(5) table, has the form:
 .IP \fBunix\fR:\fIpathname\fR
-Connect to the UNIX-domain server that is bound to the specified
+Connect to the local UNIX-domain server that is bound to the specified
 \fIpathname\fR. If the process runs chrooted, an absolute pathname
 is interpreted relative to the changed root directory.
 .IP "\fBinet\fR:\fIhost\fR, \fBinet\fB:\fIhost\fR:\fIport\fR (symbolic host)"
 .IP "\fBinet\fR:[\fIaddr\fR], \fBinet\fR:[\fIaddr\fR]:\fIport\fR (numeric host)"
-Connect to the specified IPV4 TCP port on the specified host. If no
-port is specified, connect to the port defined as \fBlmtp\fR in
-\fBservices\fR(4).
+Connect to the specified IPV4 TCP port on the specified local or
+remote host. If no port is specified, connect to the port defined as
+\fBlmtp\fR in \fBservices\fR(4).
 If no such service is found, the \fBlmtp_tcp_port\fR configuration
 parameter (default value of 24) will be used.
 
@@ -59,6 +59,7 @@ RFC 1651 (SMTP service extensions)
 RFC 1870 (Message Size Declaration)
 RFC 2033 (LMTP protocol)
 RFC 2197 (Pipelining)
+RFC 2554 (AUTH command)
 .SH DIAGNOSTICS
 .ad
 .fi
@@ -101,6 +102,27 @@ Do not wait for the server response after sending QUIT.
 .IP \fBlmtp_tcp_port\fR
 The TCP port to be used when connecting to a LMTP server.  Used as
 backup if the \fBlmtp\fR service is not found in \fBservices\fR(4).
+.SH "Authentication controls"
+.IP \fBlmtp_enable_sasl_auth\fR
+Enable per-session authentication as per RFC 2554 (SASL).
+By default, Postfix is built without SASL support.
+.IP \fBlmtp_sasl_password_maps\fR
+Lookup tables with per-host or domain \fIname\fR:\fIpassword\fR entries.
+No entry for a host means no attempt to authenticate.
+.IP \fBlmtp_sasl_security_options\fR
+Zero or more of the following.
+.RS
+.IP \fBnoplaintext\fR
+Disallow authentication methods that use plaintext passwords.
+.IP \fBnoactive\fR
+Disallow authentication methods that are vulnerable to non-dictionary
+active attacks.
+.IP \fBnodictionary\fR
+Disallow authentication methods that are vulnerable to passive
+dictionary attack.
+.IP \fBnoanonymous\fR
+Disallow anonymous logins.
+.RE
 .SH "Resource controls"
 .ad
 .fi
index b0795386df7d5139564dfd7e940e7da0c0c69a03..c0929a6acba14f09b6769d874c09c0e5f5f7d3eb 100644 (file)
@@ -312,9 +312,9 @@ forwarding, delivery to command or file. Specify zero or more of:
 forwarding mail is not recommended.
 .IP \fBrecipient_delimiter\fR
 Separator between username and address extension.
-.IP \fBtest_home_directory\fR
+.IP \fBrequire_home_directory\fR
 Require that a recipient's home directory is accessible by the
-recipient before attempting delivery.
+recipient before attempting delivery. Defer delivery otherwise.
 .SH Mailbox delivery
 .ad
 .fi
@@ -351,7 +351,7 @@ Time in seconds between successive attempts to acquire
 an exclusive lock.
 .IP \fBstale_lock_time\fR
 Limit the time after which a stale lock is removed.
-.IP \fBmailbox__delivery_lock\fR
+.IP \fBmailbox_delivery_lock\fR
 What file locking method(s) to use when delivering to a UNIX-style
 mailbox.
 The default setting is system dependent.  For a list of available
@@ -375,13 +375,19 @@ The default limit is taken from the
 Limit the number of recipients per message delivery.
 The default limit is taken from the
 \fBdefault_destination_recipient_limit\fR parameter.
+.IP \fBmailbox_size_limit\fR
+Limit the size of a mailbox etc. file (any file that is
+written to upon delivery).
+Set to zero to disable the limit.
 .SH "Security controls"
 .ad
 .fi
 .IP \fBallow_mail_to_commands\fR
 Restrict the usage of mail delivery to external command.
+Specify zero or more of: \fBalias\fR, \fBforward\fR, \fBinclude\fR.
 .IP \fBallow_mail_to_files\fR
 Restrict the usage of mail delivery to external file.
+Specify zero or more of: \fBalias\fR, \fBforward\fR, \fBinclude\fR.
 .IP \fBcommand_expansion_filter\fR
 What characters are allowed to appear in $name expansions of
 mailbox_command. Illegal characters are replaced by underscores.
index f8eccc0cb5ac70e8f3241e71679f84e79d6462aa..c544a890d5c6b67305e1e428bfd811da239acc96 100644 (file)
@@ -71,7 +71,7 @@ a configuration change.
 .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.
-.IP \fBallow_broken_auth_clients\fR
+.IP \fBbroken_sasl_auth_clients\fR
 Support older Microsoft clients that mis-implement the AUTH
 protocol, and that expect an EHLO response of "250 AUTH=list"
 instead of "250 AUTH list".
@@ -81,11 +81,13 @@ The name of a mail delivery transport that filters mail and that
 either bounces mail or re-injects the result back into Postfix.
 This parameter uses the same syntax as the right-hand side of
 a Postfix transport table.
-.SH "Authenication controls"
+.SH "Authentication controls"
 .IP \fBenable_sasl_authentication\fR
 Enable per-session authentication as per RFC 2554 (SASL).
 This functionality is available only when explicitly selected
 at program build time and explicitly enabled at runtime.
+.IP \fBsmtpd_sasl_local_domain\fR
+The name of the local authentication realm.
 .IP \fBsmtpd_sasl_security_options\fR
 Zero or more of the following.
 .RS
index 230cdc91af0b71cd7d5a0c6a0d8021655161afab..946fbcf90e28fa3f74838a3480012365c7e6f94e 100644 (file)
@@ -15,3 +15,7 @@ mansect               extract manual page section from source file
 srctoman       extract man page from source file
                usage: srctoman file.suffix
                usage: srctoman -type file
+
+man2html       quick script to htmlize nroff -man output
+
+postlink       quick script to hyperlink man2html output
diff --git a/postfix/mantools/man2html b/postfix/mantools/man2html
new file mode 100755 (executable)
index 0000000..5635571
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+# Crude script to convert formatted manual pages to HTML
+
+echo '<html> <head> </head> <body> <pre>'
+
+sed '
+       s/\([<>&]\)\b\1/\1/g
+       s/&/\&amp;/g
+       s/</\&lt;/g
+       s/>/\&gt;/g
+       s;_\b\(.\);<i>\1</i>;g
+       s;.\b\(.\);<b>\1</b>;g
+       s;</i><i>;;g
+       s;</b><b>;;g
+' "$@"
+
+echo '</pre> </body> </html>'
diff --git a/postfix/mantools/postlink b/postfix/mantools/postlink
new file mode 100755 (executable)
index 0000000..d9c57a9
--- /dev/null
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+# Crude script to make formatted Postfix man pages clickable.
+# RFC links by Ralf Hildebrandt.
+
+exec sed '
+    :again
+       /-[</bB>]*$/{
+           N
+           b again
+       }
+       s/[<bB>]*bounce[</bB>]*(8)/<a href="bounce.8.html">&<\/a>/
+       s/[<bB>]*cleanup[</bB>]*(8)/<a href="cleanup.8.html">&<\/a>/
+       s/[<bB>]*defer[</bB>]*(8)/<a href="defer.8.html">&<\/a>/
+       s/[<bB>]*error[</bB>]*(8)/<a href="error.8.html">&<\/a>/
+       s/[<bB>]*flush[</bB>]*(8)/<a href="flushd.8.html">&<\/a>/
+       s/[<bB>]*local[</bB>]*(8)/<a href="local.8.html">&<\/a>/
+       s/[<bB>]*mas[-</bB>]*\n*[ <bB>]*ter[</bB>]*(8)/<a href="master.8.html">&<\/a>/
+       s/[<bB>]*pickup[</bB>]*(8)/<a href="pickup.8.html">&<\/a>/
+       s/[<bB>]*pipe[</bB>]*(8)/<a href="pipe.8.html">&<\/a>/
+       s/[<bB>]*qmgr[</bB>]*(8)/<a href="qmgr.8.html">&<\/a>/
+       s/[<bB>]*showq[</bB>]*(8)/<a href="showq.8.html">&<\/a>/
+       s/[<bB>]*smtp[</bB>]*(8)/<a href="smtp.8.html">&<\/a>/
+       s/[<bB>]*smtpd[</bB>]*(8)/<a href="smtpd.8.html">&<\/a>/
+       s/[<bB>]*spawn[</bB>]*(8)/<a href="spawn.8.html">&<\/a>/
+       s/[<bB>]*triv[-</bB>]*\n*[ <bB>]*ial[-</bB>]*\n*[ <bB>]*rewrite[</bB>]*(8)/<a href="trivial-rewrite.8.html">&<\/a>/
+       s/[<bB>]*mailq[</bB>]*(1)/<a href="mailq.1.html">&<\/a>/
+       s/[<bB>]*newaliases[</bB>]*(1)/<a href="newaliases.1.html">&<\/a>/
+       s/[<bB>]*postalias[</bB>]*(1)/<a href="postalias.1.html">&<\/a>/
+       s/[<bB>]*postcat[</bB>]*(1)/<a href="postcat.1.html">&<\/a>/
+       s/[<bB>]*postconf[</bB>]*(1)/<a href="postconf.1.html">&<\/a>/
+       s/[<bB>]*postdrop[</bB>]*(1)/<a href="postdrop.1.html">&<\/a>/
+       s/[<bB>]*postfix[</bB>]*(1)/<a href="postfix.1.html">&<\/a>/
+       s/[<bB>]*postkick[</bB>]*(1)/<a href="postkick.1.html">&<\/a>/
+       s/[<bB>]*postlock[</bB>]*(1)/<a href="postlock.1.html">&<\/a>/
+       s/[<bB>]*postlog[</bB>]*(1)/<a href="postlog.1.html">&<\/a>/
+       s/[<bB>]*postmap[</bB>]*(1)/<a href="postmap.1.html">&<\/a>/
+       s/[<bB>]*send[-</bB>]*\n*[ <bB>]*mail[</bB>]*(1)/<a href="sendmail.1.html">&<\/a>/
+       s/[<bB>]*access[</bB>]*(5)/<a href="access.5.html">&<\/a>/
+       s/[<bB>]*aliases[</bB>]*(5)/<a href="aliases.5.html">&<\/a>/
+       s/[<bB>]*canonical[</bB>]*(5)/<a href="canonical.5.html">&<\/a>/
+       s/[<bB>]*etrn[</bB>]*(5)/<a href="etrn.5.html">&<\/a>/
+       s/[<bB>]*pcre[</bBiI>]*_[</iIbB>]*table[</bB>]*(5)/<a href="pcre_table.5.html">&<\/a>/
+       s/[<bB>]*regexp[</bBiI>]*_[</iIbB>]*table[</bB>]*(5)/<a href="regexp_table.5.html">&<\/a>/
+       s/[<bB>]*relocated[</bB>]*(5)/<a href="relocated.5.html">&<\/a>/
+       s/[<bB>]*trans[-</bB>]*\n*[ <bB>]*port[</bB>]*(5)/<a href="transport.5.html">&<\/a>/
+       s/[<bB>]*virtual[</bB>]*(5)/<a href="virtual.5.html">&<\/a>/
+       s/[<bB>]*virtual[</bB>]*(8)/<a href="virtual.8.html">&<\/a>/
+       s/\(<a href="[^"]*">\)\([<bB>]*[a-z0-9-]*[-</bB>]*\)\(\n *\)\([<bB>]*[a-z0-9-]*[</bB>]*([0-9])\)\(<\/a>\)/\1\2\5\3\1\4\5/
+       s/RFC *\([0-9]*\)/<a href="http:\/\/www.faqs.org\/rfcs\/rfc\1.html">&<\/a>/
+' "$@"
index 1402fb6281a95d07101831acad6d1819dbe05300..23b4fd96015ff9c444039c81ce14d00aa807d2b2 100644 (file)
 #      Reject the address etc. that matches the pattern. A generic
 #      error response message is generated.
 # .IP \fBOK\fR
-# .IP "\fIAny other text\fR"
 #      Accept the address etc. that matches the pattern.
+# .IP \fIrestriction...\fR
+#      Apply the named UCE restriction (\fBpermit\fR, \fRreject\fR,
+#      \fBreject_unauth_destination\fR, and so on).
 # REGULAR EXPRESSION TABLES
 # .ad
 # .fi
index fedd6a8700093ca5ab9590fedc537f68b139b06f..f08923fc0b89bc871d445fa19e1565a616a7e4b3 100644 (file)
@@ -168,7 +168,7 @@ static int dns_query(const char *name, int type, int flags,
     len = res_search((char *) name, C_IN, type, reply->buf, sizeof(reply->buf));
     if (len < 0) {
        if (why)
-           vstring_sprintf(why, "Name service error for domain %s: %s",
+           vstring_sprintf(why, "Name service error for %s: %s",
                            name, dns_strerror(h_errno));
        if (msg_verbose)
            msg_info("dns_query: %s (%s): %s",
@@ -241,6 +241,50 @@ static int dns_get_fixed(unsigned char *pos, DNS_FIXED *fixed)
     return (DNS_OK);
 }
 
+/* valid_rr_name - validate hostname in resource record */
+
+static int valid_rr_name(const char *name, const char *location,
+                                unsigned type, DNS_REPLY *reply)
+{
+    char    temp[DNS_NAME_LEN];
+    char   *query_name;
+    int     len;
+    char   *gripe;
+    int     result;
+
+    /*
+     * People aren't supposed to specify numeric names where domain names are
+     * required, but it "works" with some mailers anyway, so people complain
+     * when software doesn't bend over backwards.
+     */
+#define PASS_NAME      1
+#define REJECT_NAME    0
+
+    if (valid_hostaddr(name, DONT_GRIPE)) {
+       result = PASS_NAME;
+       gripe = "numeric domain name";
+    } else if (!valid_hostname(name, DO_GRIPE)) {
+       result = REJECT_NAME;
+       gripe = "malformed domain name";
+    } else {
+       result = PASS_NAME;
+       gripe = 0;
+    }
+
+    /*
+     * If we have a gripe, show some context, including the name used in the
+     * query and the type of reply that we're looking at.
+     */
+    if (gripe) {
+       len = dn_expand(reply->buf, reply->end, reply->query_start,
+                       temp, DNS_NAME_LEN);
+       query_name = (len < 0 ? "*unparsable*" : temp);
+       msg_warn("%s in %s of %s record for %s: %.100s",
+                gripe, location, dns_strtype(type), query_name, name);
+    }
+    return (result);
+}
+
 /* dns_get_rr - extract resource record from name server reply */
 
 static DNS_RR *dns_get_rr(DNS_REPLY *reply, unsigned char *pos,
@@ -270,7 +314,7 @@ static DNS_RR *dns_get_rr(DNS_REPLY *reply, unsigned char *pos,
     case T_PTR:
        if (dn_expand(reply->buf, reply->end, pos, temp, sizeof(temp)) < 0)
            return (0);
-       if (!valid_hostname(temp))
+       if (!valid_rr_name(temp, "resource data", fixed->type, reply))
            return (0);
        data_len = strlen(temp) + 1;
        break;
@@ -278,7 +322,7 @@ static DNS_RR *dns_get_rr(DNS_REPLY *reply, unsigned char *pos,
        GETSHORT(pref, pos);
        if (dn_expand(reply->buf, reply->end, pos, temp, sizeof(temp)) < 0)
            return (0);
-       if (!valid_hostname(temp))
+       if (!valid_rr_name(temp, "resource data", fixed->type, reply))
            return (0);
        data_len = strlen(temp) + 1;
        break;
@@ -315,7 +359,7 @@ static int dns_get_alias(DNS_REPLY *reply, unsigned char *pos,
        msg_panic("dns_get_alias: bad type %s", dns_strtype(fixed->type));
     if (dn_expand(reply->buf, reply->end, pos, cname, c_len) < 0)
        return (DNS_RETRY);
-    if (!valid_hostname(cname))
+    if (!valid_rr_name(cname, "resource data", fixed->type, reply))
        return (DNS_RETRY);
     return (DNS_OK);
 }
@@ -369,10 +413,6 @@ static int dns_get_answer(DNS_REPLY *reply, int type,
        len = dn_expand(reply->buf, reply->end, pos, rr_name, DNS_NAME_LEN);
        if (len < 0)
            CORRUPT;
-       if (!valid_hostname(rr_name))
-           CORRUPT;
-       if (fqdn)
-           vstring_strcpy(fqdn, rr_name);
        pos += len;
 
        /*
@@ -382,6 +422,10 @@ static int dns_get_answer(DNS_REPLY *reply, int type,
            CORRUPT;
        if (dns_get_fixed(pos, &fixed) != DNS_OK)
            CORRUPT;
+       if (!valid_rr_name(rr_name, "resource name", fixed.type, reply))
+           CORRUPT;
+       if (fqdn)
+           vstring_strcpy(fqdn, rr_name);
        if (msg_verbose)
            msg_info("dns_get_answer: type %s for %s",
                     dns_strtype(fixed.type), rr_name);
@@ -434,7 +478,7 @@ int     dns_lookup(const char *name, unsigned type, unsigned flags,
     /*
      * The Linux resolver misbehaves when given an invalid domain name.
      */
-    if (!valid_hostname(name)) {
+    if (!valid_hostname(name, DONT_GRIPE)) {
        if (why)
            vstring_sprintf(why, "Name service error for %s: invalid name",
                            name);
index f6f1fdff4323ddd96b92fbc894be02187af7060f..5be7113531a5518cf2fad859325847fda412755e 100644 (file)
@@ -60,6 +60,9 @@ static struct dns_type_map dns_type_map[] = {
 #ifdef T_A
     T_A, "A",
 #endif
+#ifdef T_AAAA
+    T_AAAA, "AAAA",
+#endif
 #ifdef T_NS
     T_NS, "NS",
 #endif
index 0ec9840d972d3964f32a436498564e6e6bbdf9d4..d35cc5813f91040a9e2bea6595824675b520b607 100644 (file)
@@ -466,14 +466,14 @@ static void flush_service(VSTREAM *client_stream, char *unused_service,
            site = vstring_alloc(10);
            queue_id = vstring_alloc(10);
            if (mail_command_read(client_stream, "%s %s", site, queue_id) == 2
-               && valid_hostname(STR(site))
+               && valid_hostname(STR(site), DONT_GRIPE)
                && mail_queue_id_ok(STR(queue_id)))
                status = flush_add_service(lowercase(STR(site)), STR(queue_id));
            mail_print(client_stream, "%d", status);
        } else if (STREQ(STR(request), FLUSH_REQ_SEND)) {
            site = vstring_alloc(10);
            if (mail_command_read(client_stream, "%s", site) == 1
-               && valid_hostname(STR(site)))
+               && valid_hostname(STR(site), DONT_GRIPE))
                status = flush_send_service(lowercase(STR(site)));
            mail_print(client_stream, "%d", status);
        } else if (STREQ(STR(request), FLUSH_REQ_REFRESH)
index fac2db938329c5c6eceb987ff413e40915ccfbe3..43d75aed068bd2a9273837c2e84fc1f3285cf091 100644 (file)
@@ -346,6 +346,7 @@ deliver_flock.o: ../../include/sys_defs.h
 deliver_flock.o: ../../include/vstring.h
 deliver_flock.o: ../../include/vbuf.h
 deliver_flock.o: ../../include/myflock.h
+deliver_flock.o: ../../include/iostuff.h
 deliver_flock.o: mail_params.h
 deliver_flock.o: deliver_flock.h
 deliver_pass.o: deliver_pass.c
@@ -387,6 +388,7 @@ dot_lockfile.o: ../../include/vstring.h
 dot_lockfile.o: ../../include/vbuf.h
 dot_lockfile.o: ../../include/stringops.h
 dot_lockfile.o: ../../include/mymalloc.h
+dot_lockfile.o: ../../include/iostuff.h
 dot_lockfile.o: mail_params.h
 dot_lockfile.o: dot_lockfile.h
 dot_lockfile_as.o: dot_lockfile_as.c
@@ -428,13 +430,6 @@ header_opts.o: header_opts.h
 is_header.o: is_header.c
 is_header.o: ../../include/sys_defs.h
 is_header.o: is_header.h
-local_transport.o: local_transport.c
-local_transport.o: ../../include/sys_defs.h
-local_transport.o: ../../include/msg.h
-local_transport.o: ../../include/mymalloc.h
-local_transport.o: string_list.h
-local_transport.o: mail_params.h
-local_transport.o: local_transport.h
 mail_addr.o: mail_addr.c
 mail_addr.o: ../../include/sys_defs.h
 mail_addr.o: ../../include/stringops.h
@@ -774,6 +769,8 @@ mkmap_open.o: ../../include/dict.h
 mkmap_open.o: ../../include/vstream.h
 mkmap_open.o: ../../include/vbuf.h
 mkmap_open.o: ../../include/argv.h
+mkmap_open.o: ../../include/dict_db.h
+mkmap_open.o: ../../include/dict_dbm.h
 mkmap_open.o: ../../include/sigdelay.h
 mkmap_open.o: ../../include/mymalloc.h
 mkmap_open.o: ../../include/myflock.h
@@ -784,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 aa3f8b0f89a800e53ee657f6ef0e5639304ac594..35a6bcb33d22449ecd1da1e8ce624825de9c8ee3 100644 (file)
 
 #include <vstring.h>
 #include <myflock.h>
+#include <iostuff.h>
 
 /* Global library. */
 
 #include "mail_params.h"
 #include "deliver_flock.h"
 
+/* Application-specific. */
+
+#define MILLION        1000000
+
 /* deliver_flock - lock open file for mail delivery */
 
 int     deliver_flock(int fd, int lock_style, VSTRING *why)
@@ -69,7 +74,7 @@ int     deliver_flock(int fd, int lock_style, VSTRING *why)
            return (0);
        if (i >= var_flock_tries)
            break;
-       sleep(var_flock_delay);
+       rand_sleep(var_flock_delay * MILLION, var_flock_delay * MILLION / 2);
     }
     if (why)
        vstring_sprintf(why, "unable to lock for exclusive access: %m");
index bb898948fce9561a06cbcb3ffcb0a93d418b58cc..9d0a2bef31ce26a1e59e6203525a059813861bb3 100644 (file)
@@ -31,7 +31,7 @@
 /* DIAGNOSTICS
 /*     dot_lockfile() returns 0 upon success. In case of failure, the
 /*     result is -1, and the errno variable is set appropriately:
-/*     EEXIST when a "fresh" lock file already exists; other values as 
+/*     EEXIST when a "fresh" lock file already exists; other values as
 /*     appropriate.
 /* CONFIGURATION PARAMETERS
 /*     deliver_lock_attempts, how many times to try to create a lock
 #include <vstring.h>
 #include <stringops.h>
 #include <mymalloc.h>
+#include <iostuff.h>
 
 /* Global library. */
 
 #include "mail_params.h"
 #include "dot_lockfile.h"
 
+/* Application-specific. */
+
+#define MILLION        1000000
+
 /* dot_lockfile - create user.lock file */
 
 int     dot_lockfile(const char *path, VSTRING *why)
@@ -113,7 +118,7 @@ int     dot_lockfile(const char *path, VSTRING *why)
                    if (errno != ENOENT)
                        break;
 
-       sleep(var_flock_delay);
+       rand_sleep(var_flock_delay * MILLION, var_flock_delay * MILLION / 2);
     }
     if (status && why)
        vstring_sprintf(why, "unable to create lock file %s: %m", lock_file);
index 5d1c60fd8011b08f75719ce854aba54236ee1af2..ed04630aad6cca6a29ea5e7eaa4b0974f5e2af5a 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;
@@ -280,7 +282,7 @@ void    mail_params_init()
        VAR_INET_INTERFACES, DEF_INET_INTERFACES, &var_inet_interfaces, 1, 0,
        VAR_DOUBLE_BOUNCE, DEF_DOUBLE_BOUNCE, &var_double_bounce_sender, 1, 0,
        VAR_DEFAULT_PRIVS, DEF_DEFAULT_PRIVS, &var_default_privs, 1, 0,
-       VAR_ALIAS_DB_MAP, DEF_ALIAS_DB_MAP, &var_alias_db_map, 1, 0,
+       VAR_ALIAS_DB_MAP, DEF_ALIAS_DB_MAP, &var_alias_db_map, 0, 0,
        VAR_MAIL_VERSION, DEF_MAIL_VERSION, &var_mail_version, 1, 0,
        VAR_DB_TYPE, DEF_DB_TYPE, &var_db_type, 1, 0,
        VAR_HASH_QUEUE_NAMES, DEF_HASH_QUEUE_NAMES, &var_hash_queue_names, 1, 0,
@@ -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[] = {
@@ -340,8 +343,10 @@ void    mail_params_init()
      * the domain.
      */
     get_mail_conf_str_fn_table(function_str_defaults);
-    if (!valid_hostname(var_myhostname) || !valid_hostname(var_mydomain))
-       msg_fatal("host or domain name configuration error");
+    if (!valid_hostname(var_myhostname, DO_GRIPE)
+       || !valid_hostname(var_mydomain, DO_GRIPE))
+       msg_fatal("main.cf configuration error: bad %s or %s parameter value",
+                 VAR_MYHOSTNAME, VAR_MYDOMAIN);
 
     /*
      * Variables that are needed by almost every program.
index 93a5bf9cdbe5075de430fa6bd6feec60fb7a54dd..294fd1fc5fdce95f9ab6aeebd807e8d75788d616 100644 (file)
@@ -241,7 +241,7 @@ extern bool var_strict_rfc821_env;
   * Standards violation: send "250 AUTH=list" in order to accomodate broken
   * Microsoft clients.
   */
-#define VAR_BROKEN_AUTH_CLNTS  "allow_broken_auth_clients"
+#define VAR_BROKEN_AUTH_CLNTS  "broken_sasl_auth_clients"
 #define DEF_BROKEN_AUTH_CLNTS  0
 extern bool var_broken_auth_clients;
 
@@ -379,6 +379,14 @@ extern char *var_forward_path;
 #define VAR_MAILBOX_LOCK       "mailbox_delivery_lock"
 extern char *var_mailbox_lock;
 
+ /*
+  * Mailbox size limit. This used to be enforced as a side effect of the way
+  * the message size limit is implemented, but that is not clean.
+  */
+#define VAR_MAILBOX_LIMIT      "mailbox_size_limit"
+#define DEF_MAILBOX_LIMIT      (DEF_MESSAGE_LIMIT * 5)
+extern int var_mailbox_limit;
+
  /*
   * Miscellaneous.
   */
@@ -484,12 +492,12 @@ extern int var_stack_rcpt_limit;
   */
 #define VAR_DELIVERY_SLOT_COST "default_delivery_slot_cost"
 #define _DELIVERY_SLOT_COST    "_delivery_slot_cost"
-#define DEF_DELIVERY_SLOT_COST 10
+#define DEF_DELIVERY_SLOT_COST 5
 extern int var_delivery_slot_cost;
 
 #define VAR_DELIVERY_SLOT_LOAN "default_delivery_slot_loan"
 #define _DELIVERY_SLOT_LOAN    "_delivery_slot_loan"
-#define DEF_DELIVERY_SLOT_LOAN 5
+#define DEF_DELIVERY_SLOT_LOAN 3
 extern int var_delivery_slot_loan;
 
 #define VAR_DELIVERY_SLOT_DISCOUNT     "default_delivery_slot_discount"
@@ -522,6 +530,10 @@ extern int var_init_dest_concurrency;
 #define DEF_DEST_CON_LIMIT     10
 extern int var_dest_con_limit;
 
+#define VAR_LOCAL_CON_LIMIT    "local" _DEST_CON_LIMIT
+#define DEF_LOCAL_CON_LIMIT    2
+extern int var_local_con_lim;
+
  /*
   * Queue manager: default number of recipients per transaction.
   */
@@ -532,6 +544,7 @@ extern int var_dest_rcpt_limit;
 
 #define VAR_LOCAL_RCPT_LIMIT   "local" _DEST_RCPT_LIMIT        /* XXX */
 #define DEF_LOCAL_RCPT_LIMIT   1       /* XXX */
+extern int var_local_rcpt_lim;
 
  /*
   * Queue manager: default delay before retrying a dead transport.
@@ -609,7 +622,7 @@ extern int var_debug_peer_level;
   * subdirectories, and how deep the forest is.
   */
 #define VAR_HASH_QUEUE_NAMES   "hash_queue_names"
-#define DEF_HASH_QUEUE_NAMES   "active,bounce,defer,flush"
+#define DEF_HASH_QUEUE_NAMES   "incoming,active,deferred,bounce,defer,flush"
 extern char *var_hash_queue_names;
 
 #define VAR_HASH_QUEUE_DEPTH   "hash_queue_depth"
@@ -749,6 +762,54 @@ extern char *var_smtp_sasl_passwd;
 #define DEF_SMTP_SASL_OPTS     "noplaintext, noanonymous"
 extern char *var_smtp_sasl_opts;
 
+ /*
+  * LMTP server. The soft error limit determines how many errors an LMTP
+  * client may make before we start to slow down; the hard error limit
+  * determines after how many client errors we disconnect.
+  */
+#define VAR_LMTPD_BANNER       "lmtpd_banner"
+#define DEF_LMTPD_BANNER       "$myhostname $mail_name"
+extern char *var_lmtpd_banner;
+
+#define VAR_LMTPD_TMOUT                "lmtpd_timeout"
+#define DEF_LMTPD_TMOUT                "300s"
+extern int var_lmtpd_tmout;
+
+#define VAR_LMTPD_RCPT_LIMIT   "lmtpd_recipient_limit"
+#define DEF_LMTPD_RCPT_LIMIT   1000
+extern int var_lmtpd_rcpt_limit;
+
+#define VAR_LMTPD_SOFT_ERLIM   "lmtpd_soft_error_limit"
+#define DEF_LMTPD_SOFT_ERLIM   10
+extern int var_lmtpd_soft_erlim;
+
+#define VAR_LMTPD_HARD_ERLIM   "lmtpd_hard_error_limit"
+#define DEF_LMTPD_HARD_ERLIM   100
+extern int var_lmtpd_hard_erlim;
+
+#define VAR_LMTPD_ERR_SLEEP    "lmtpd_error_sleep_time"
+#define DEF_LMTPD_ERR_SLEEP    "5s"
+extern int var_lmtpd_err_sleep;
+
+#define VAR_LMTPD_JUNK_CMD     "lmtpd_junk_command_limit"
+#define DEF_LMTPD_JUNK_CMD     1000
+extern int var_lmtpd_junk_cmd_limit;
+
+ /*
+  * SASL authentication support, LMTP server side.
+  */
+#define VAR_LMTPD_SASL_ENABLE  "lmtpd_sasl_auth_enable"
+#define DEF_LMTPD_SASL_ENABLE  0
+extern bool var_lmtpd_sasl_enable;
+
+#define VAR_LMTPD_SASL_OPTS    "lmtpd_sasl_security_options"
+#define DEF_LMTPD_SASL_OPTS    "noanonymous"
+extern char *var_lmtpd_sasl_opts;
+
+#define VAR_LMTPD_SASL_REALM   "lmtpd_sasl_local_domain"
+#define DEF_LMTPD_SASL_REALM   "$myhostname"
+extern char *var_lmtpd_sasl_realm;
+
  /*
   * SASL authentication support, LMTP client side.
   */
@@ -888,7 +949,7 @@ extern int var_fork_delay;
   * When locking a mailbox, how often to try and how long to wait.
   */
 #define VAR_FLOCK_TRIES          "deliver_lock_attempts"
-#define DEF_FLOCK_TRIES          10
+#define DEF_FLOCK_TRIES          20
 extern int var_flock_tries;
 
 #define VAR_FLOCK_DELAY          "deliver_lock_delay"
@@ -934,6 +995,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;
@@ -992,7 +1061,7 @@ extern int var_unk_client_code;
 
 #define REJECT_INVALID_HOSTNAME        "reject_invalid_hostname"
 #define VAR_BAD_NAME_CODE      "invalid_hostname_reject_code"
-#define DEF_BAD_NAME_CODE      501
+#define DEF_BAD_NAME_CODE      501     /* SYNTAX */
 extern int var_bad_name_code;
 
 #define REJECT_UNKNOWN_HOSTNAME        "reject_unknown_hostname"
@@ -1004,7 +1073,7 @@ extern int var_unk_name_code;
 #define REJECT_NON_FQDN_SENDER "reject_non_fqdn_sender"
 #define REJECT_NON_FQDN_RCPT   "reject_non_fqdn_recipient"
 #define VAR_NON_FQDN_CODE      "non_fqdn_reject_code"
-#define DEF_NON_FQDN_CODE      504
+#define DEF_NON_FQDN_CODE      504     /* POLICY */
 extern int var_non_fqdn_code;
 
 #define REJECT_UNKNOWN_SENDDOM "reject_unknown_sender_domain"
@@ -1133,30 +1202,34 @@ extern char *var_export_environ;
  /*
   * Tunables for the "virtual" local delivery agent
   */
-#define VAR_VIRT_MAILBOX_MAPS  "virtual_mailbox_maps"
-#define DEF_VIRT_MAILBOX_MAPS  ""
-extern char *var_mailbox_maps;
+#define VAR_VIRT_MAILBOX_MAPS          "virtual_mailbox_maps"
+#define DEF_VIRT_MAILBOX_MAPS          ""
+extern char *var_virt_mailbox_maps;
 
-#define VAR_VIRT_UID_MAPS      "virtual_uid_maps"
-#define DEF_VIRT_UID_MAPS      ""
-extern char *var_uid_maps;
+#define VAR_VIRT_UID_MAPS              "virtual_uid_maps"
+#define DEF_VIRT_UID_MAPS              ""
+extern char *var_virt_uid_maps;
 
-#define VAR_VIRT_GID_MAPS      "virtual_gid_maps"
-#define DEF_VIRT_GID_MAPS      ""
-extern char *var_gid_maps;
+#define VAR_VIRT_GID_MAPS              "virtual_gid_maps"
+#define DEF_VIRT_GID_MAPS              ""
+extern char *var_virt_gid_maps;
 
-#define VAR_VIRT_USEDOTLOCK    "virtual_usedotlock"
-#define DEF_VIRT_USEDOTLOCK    0
-extern bool var_virt_usedotlock;
-
-#define VAR_VIRT_MINUID                "virtual_minimum_uid"
-#define DEF_VIRT_MINUID                100
+#define VAR_VIRT_MINUID                        "virtual_minimum_uid"
+#define DEF_VIRT_MINUID                        100
 extern int var_virt_minimum_uid;
 
-#define VAR_VIRT_MAILBOX_BASE  "virtual_mailbox_base"
-#define DEF_VIRT_MAILBOX_BASE  ""
+#define VAR_VIRT_MAILBOX_BASE          "virtual_mailbox_base"
+#define DEF_VIRT_MAILBOX_BASE          ""
 extern char *var_virt_mailbox_base;
 
+#define VAR_VIRT_MAILBOX_LIMIT         "virtual_mailbox_limit"
+#define DEF_VIRT_MAILBOX_LIMIT         (5 * DEF_MESSAGE_LIMIT)
+extern int var_virt_mailbox_limit;
+
+#define VAR_VIRT_MAILBOX_LOCK          "virtual_mailbox_lock"
+#define DEF_VIRT_MAILBOX_LOCK          "fcntl"
+extern char *var_virt_mailbox_lock;
+
 /* LICENSE
 /* .ad
 /* .fi
index cca871749692444de00b1870911d9bdc058c0d7b..5fc18640ec38c02b2ebfc3529f58c25dc68cae84 100644 (file)
@@ -311,7 +311,7 @@ int     mail_queue_id_ok(const char *queue_id)
     /*
      * OK if in valid hostname form.
      */
-    return (valid_hostname(queue_id));
+    return (valid_hostname(queue_id, DO_GRIPE));
 }
 
 /* mail_queue_enter - make mail queue entry with locally-unique name */
@@ -416,7 +416,7 @@ VSTREAM *mail_queue_open(const char *queue_name, const char *queue_id,
      */
     if ((fp = vstream_fopen(path, flags, mode)) == 0)
        if (errno == ENOENT)
-       if ((flags & O_CREAT) == O_CREAT && mail_queue_mkdirs(path) == 0)
-           fp = vstream_fopen(path, flags, mode);
+           if ((flags & O_CREAT) == O_CREAT && mail_queue_mkdirs(path) == 0)
+               fp = vstream_fopen(path, flags, mode);
     return (fp);
 }
index f9a7fcd35ef9a0819a09699d28ded8d6615355d0..075638f2bead30a1c7a2f1f5fb4fabbbf7a0d848 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Release-20010120"
+#define DEF_MAIL_VERSION       "Release-20010228"
 extern char *var_mail_version;
 
 /* LICENSE
index ad7a903cb4352562af47b4ca81bc5cd8443866df..593f7631739befeacda6d7033214cb71a0672c8f 100644 (file)
@@ -60,6 +60,8 @@
 
 #include <msg.h>
 #include <dict.h>
+#include <dict_db.h>
+#include <dict_dbm.h>
 #include <sigdelay.h>
 #include <mymalloc.h>
 #include <myflock.h>
@@ -79,11 +81,11 @@ typedef struct {
 
 MKMAP_OPEN_INFO mkmap_types[] = {
 #ifdef HAS_DBM
-    "dbm", mkmap_dbm_open,
+    DICT_TYPE_DBM, mkmap_dbm_open,
 #endif
 #ifdef HAS_DB
-    "hash", mkmap_hash_open,
-    "btree", mkmap_btree_open,
+    DICT_TYPE_HASH, mkmap_hash_open,
+    DICT_TYPE_BTREE, mkmap_btree_open,
 #endif
     0,
 };
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 63d408c2e54b57dbd3d0f2ba3aba73064d13d586..5e3affa5a843b1fb3cfdba93edd8a9f2982caf51 100644 (file)
@@ -79,7 +79,7 @@ PEER_NAME *peer_name(int sock)
            peer.type = PEER_TYPE_INET;
            hp = gethostbyaddr((char *) &(sin.sin_addr),
                               sizeof(sin.sin_addr), AF_INET);
-           peer.name = (hp && valid_hostname(hp->h_name) ?
+           peer.name = (hp && valid_hostname(hp->h_name, DO_GRIPE) ?
                         hp->h_name : "unknown");
            peer.addr = inet_ntoa(sin.sin_addr);
            return (&peer);
index 6e483318590432904934aa4e359f560b878c6f71..9821cf6af489375037a8f60af0a8ab6dfd4db20e 100644 (file)
@@ -116,6 +116,8 @@ lmtp_chat.o: ../../include/mail_params.h
 lmtp_chat.o: ../../include/mail_addr.h
 lmtp_chat.o: ../../include/post_mail.h
 lmtp_chat.o: ../../include/cleanup_user.h
+lmtp_chat.o: ../../include/mail_error.h
+lmtp_chat.o: ../../include/name_mask.h
 lmtp_chat.o: lmtp.h
 lmtp_connect.o: lmtp_connect.c
 lmtp_connect.o: ../../include/sys_defs.h
@@ -158,10 +160,10 @@ lmtp_proto.o: ../../include/record.h
 lmtp_proto.o: ../../include/rec_type.h
 lmtp_proto.o: ../../include/off_cvt.h
 lmtp_proto.o: ../../include/mark_corrupt.h
+lmtp_proto.o: ../../include/quote_821_local.h
 lmtp_proto.o: lmtp.h
 lmtp_proto.o: ../../include/argv.h
 lmtp_proto.o: lmtp_sasl.h
-lmtp_proto.o: ../../include/quote_821_local.h
 lmtp_sasl_glue.o: lmtp_sasl_glue.c
 lmtp_sasl_glue.o: ../../include/sys_defs.h
 lmtp_sasl_glue.o: ../../include/msg.h
@@ -177,12 +179,22 @@ lmtp_sasl_glue.o: ../../include/maps.h
 lmtp_sasl_glue.o: ../../include/dict.h
 lmtp_sasl_glue.o: ../../include/vstream.h
 lmtp_sasl_glue.o: ../../include/argv.h
+lmtp_sasl_glue.o: lmtp.h
+lmtp_sasl_glue.o: ../../include/deliver_request.h
+lmtp_sasl_glue.o: ../../include/recipient_list.h
 lmtp_sasl_glue.o: lmtp_sasl.h
 lmtp_sasl_proto.o: lmtp_sasl_proto.c
 lmtp_sasl_proto.o: ../../include/sys_defs.h
 lmtp_sasl_proto.o: ../../include/msg.h
 lmtp_sasl_proto.o: ../../include/mymalloc.h
 lmtp_sasl_proto.o: ../../include/mail_params.h
+lmtp_sasl_proto.o: lmtp.h
+lmtp_sasl_proto.o: ../../include/vstream.h
+lmtp_sasl_proto.o: ../../include/vbuf.h
+lmtp_sasl_proto.o: ../../include/vstring.h
+lmtp_sasl_proto.o: ../../include/argv.h
+lmtp_sasl_proto.o: ../../include/deliver_request.h
+lmtp_sasl_proto.o: ../../include/recipient_list.h
 lmtp_sasl_proto.o: lmtp_sasl.h
 lmtp_session.o: lmtp_session.c
 lmtp_session.o: ../../include/sys_defs.h
@@ -202,7 +214,6 @@ lmtp_state.o: ../../include/mymalloc.h
 lmtp_state.o: ../../include/vstring.h
 lmtp_state.o: ../../include/vbuf.h
 lmtp_state.o: ../../include/vstream.h
-lmtp_state.o: ../../include/config.h
 lmtp_state.o: ../../include/mail_conf.h
 lmtp_state.o: lmtp.h
 lmtp_state.o: ../../include/argv.h
index ec0e1c73c04cdd715fc91242e640fb622759af77..09572082adef658ac1bf08aaf4925d5cc2a374be 100644 (file)
 /*     delivery request. The destination, usually specified in the Postfix
 /*     \fBtransport\fR(5) table, has the form:
 /* .IP \fBunix\fR:\fIpathname\fR
-/*     Connect to the UNIX-domain server that is bound to the specified
+/*     Connect to the local UNIX-domain server that is bound to the specified
 /*     \fIpathname\fR. If the process runs chrooted, an absolute pathname
 /*     is interpreted relative to the changed root directory.
 /* .IP "\fBinet\fR:\fIhost\fR, \fBinet\fB:\fIhost\fR:\fIport\fR (symbolic host)"
 /* .IP "\fBinet\fR:[\fIaddr\fR], \fBinet\fR:[\fIaddr\fR]:\fIport\fR (numeric host)"
-/*     Connect to the specified IPV4 TCP port on the specified host. If no
-/*     port is specified, connect to the port defined as \fBlmtp\fR in
-/*     \fBservices\fR(4).
+/*     Connect to the specified IPV4 TCP port on the specified local or
+/*     remote host. If no port is specified, connect to the port defined as
+/*     \fBlmtp\fR in \fBservices\fR(4).
 /*     If no such service is found, the \fBlmtp_tcp_port\fR configuration
 /*     parameter (default value of 24) will be used.
 /*
@@ -458,9 +458,12 @@ static void post_init(char *unused_name, char **unused_argv)
 static void pre_init(char *unused_name, char **unused_argv)
 {
     debug_peer_init();
-#ifdef USE_SASL_AUTH
     if (var_lmtp_sasl_enable)
+#ifdef USE_SASL_AUTH
        lmtp_sasl_initialize();
+#else
+       msg_warn("%s is true, but SASL support is not compiled in",
+                VAR_LMTP_SASL_ENABLE);
 #endif
 }
 
@@ -525,6 +528,7 @@ int     main(int argc, char **argv)
     static CONFIG_BOOL_TABLE bool_table[] = {
        VAR_LMTP_CACHE_CONN, DEF_LMTP_CACHE_CONN, &var_lmtp_cache_conn,
        VAR_LMTP_SKIP_QUIT_RESP, DEF_LMTP_SKIP_QUIT_RESP, &var_lmtp_skip_quit_resp,
+       VAR_LMTP_SASL_ENABLE, DEF_LMTP_SASL_ENABLE, &var_lmtp_sasl_enable,
        0,
     };
 
index 9dd965f2bd790cb92b89a8b35b274c98fa617618..cd34d7556e4f377290cfbfa7d77bec382b7fa47c 100644 (file)
@@ -187,7 +187,7 @@ int     lmtp_lhlo(LMTP_STATE *state)
      */
     smtp_timeout_setup(state->session->stream, var_lmtp_lhlo_tmout);
     if ((except = vstream_setjmp(state->session->stream)) != 0)
-       return (smtp_stream_except(state, except, "sending LHLO"));
+       return (lmtp_stream_except(state, except, "sending LHLO"));
 
     /*
      * Read and parse the server's LMTP greeting banner.
@@ -456,7 +456,7 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
                smtp_timeout_setup(state->session->stream,
                                   *xfer_timeouts[recv_state]);
                if ((except = vstream_setjmp(state->session->stream)) != 0)
-                   RETURN(smtp_stream_except(state, except,
+                   RETURN(lmtp_stream_except(state, except,
                                              xfer_states[recv_state]));
                resp = lmtp_chat_resp(state);
 
@@ -628,7 +628,7 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
            smtp_timeout_setup(state->session->stream,
                               var_lmtp_data1_tmout);
            if ((except = vstream_setjmp(state->session->stream)) != 0)
-               RETURN(smtp_stream_except(state, except,
+               RETURN(lmtp_stream_except(state, except,
                                          "sending message body"));
 
            if (vstream_fseek(state->src, request->data_offset, SEEK_SET) < 0)
index 38b6185d32a46c382e1159dba2144a60f7b5c464..713e4d89b698ad88fcc24f3c0fd98dc0abf69512 100644 (file)
@@ -22,7 +22,7 @@
 /*     RECIPIENT *recipient;
 /*     char    *format;
 /*
-/*     int     smtp_stream_except(state, exception, description)
+/*     int     lmtp_stream_except(state, exception, description)
 /*     LMTP_STATE *state;
 /*     int     exception;
 /*     char    *description;
@@ -63,7 +63,7 @@
 /*     recipient limit is reached. The policy is: soft error: defer
 /*     delivery to this recipient; hard error: bounce this recipient.
 /*
-/*     smtp_stream_except() handles the exceptions generated by
+/*     lmtp_stream_except() handles the exceptions generated by
 /*     the smtp_stream(3) module (i.e. timeouts and I/O errors).
 /*     The \fIexception\fR argument specifies the type of problem.
 /*     The \fIdescription\fR argument describes at what stage of
@@ -270,9 +270,9 @@ void    lmtp_rcpt_fail(LMTP_STATE *state, int code, RECIPIENT *rcpt,
     state->status |= status;
 }
 
-/* smtp_stream_except - defer domain after I/O problem */
+/* lmtp_stream_except - defer domain after I/O problem */
 
-int     smtp_stream_except(LMTP_STATE *state, int code, char *description)
+int     lmtp_stream_except(LMTP_STATE *state, int code, char *description)
 {
     DELIVER_REQUEST *request = state->request;
     LMTP_SESSION *session = state->session;
@@ -285,7 +285,7 @@ int     smtp_stream_except(LMTP_STATE *state, int code, char *description)
      */
     switch (code) {
     default:
-       msg_panic("smtp_stream_except: unknown exception %d", code);
+       msg_panic("lmtp_stream_except: unknown exception %d", code);
     case SMTP_ERR_EOF:
        vstring_sprintf(why, "lost connection with %s while %s",
                        session->namaddr, description);
index 437e89f835fdade187931dfcd4f56e6b8fce1121..ff36cf9bf6573415a8887ba61616a41df04c5e8a 100644 (file)
@@ -356,6 +356,7 @@ maildir.o: ../../include/get_hostname.h
 maildir.o: ../../include/sane_fsops.h
 maildir.o: ../../include/mail_copy.h
 maildir.o: ../../include/bounce.h
+maildir.o: ../../include/defer.h
 maildir.o: ../../include/sent.h
 maildir.o: ../../include/mail_params.h
 maildir.o: local.h
index 3a1cb5fc856905835b18cc51b2257d14e4134a6e..931b2c98f3dc37ac1e7067a0711765c6c2ab7fad 100644 (file)
 /*     forwarding mail is not recommended.
 /* .IP \fBrecipient_delimiter\fR
 /*     Separator between username and address extension.
-/* .IP \fBtest_home_directory\fR
+/* .IP \fBrequire_home_directory\fR
 /*     Require that a recipient's home directory is accessible by the
-/*     recipient before attempting delivery.
+/*     recipient before attempting delivery. Defer delivery otherwise.
 /* .SH Mailbox delivery
 /* .ad
 /* .fi
 /*     an exclusive lock.
 /* .IP \fBstale_lock_time\fR
 /*     Limit the time after which a stale lock is removed.
-/* .IP \fBmailbox__delivery_lock\fR
+/* .IP \fBmailbox_delivery_lock\fR
 /*     What file locking method(s) to use when delivering to a UNIX-style
 /*     mailbox.
 /*     The default setting is system dependent.  For a list of available
 /*     Limit the number of recipients per message delivery.
 /*     The default limit is taken from the
 /*     \fBdefault_destination_recipient_limit\fR parameter.
+/* .IP \fBmailbox_size_limit\fR
+/*     Limit the size of a mailbox etc. file (any file that is
+/*     written to upon delivery).
+/*     Set to zero to disable the limit.
 /* .SH "Security controls"
 /* .ad
 /* .fi
 /* .IP \fBallow_mail_to_commands\fR
 /*     Restrict the usage of mail delivery to external command.
+/*     Specify zero or more of: \fBalias\fR, \fBforward\fR, \fBinclude\fR.
 /* .IP \fBallow_mail_to_files\fR
 /*     Restrict the usage of mail delivery to external file.
+/*     Specify zero or more of: \fBalias\fR, \fBforward\fR, \fBinclude\fR.
 /* .IP \fBcommand_expansion_filter\fR
 /*     What characters are allowed to appear in $name expansions of
 /*     mailbox_command. Illegal characters are replaced by underscores.
@@ -456,6 +462,7 @@ char   *var_deliver_hdr;
 int     var_stat_home_dir;
 int     var_mailtool_compat;
 char   *var_mailbox_lock;
+int     var_mailbox_limit;
 
 int     local_cmd_deliver_mask;
 int     local_file_deliver_mask;
@@ -621,6 +628,32 @@ static void post_init(char *unused_name, char **unused_argv)
     local_mask_init();
 }
 
+/* pre_init - pre-jail initialization */
+
+static void pre_init(char *unused_name, char **unused_argv)
+{
+
+    /*
+     * Reset the file size limit from the message size limit to the mailbox
+     * size limit. XXX This still isn't accurate because the file size limit
+     * also affects delivery to command.
+     * 
+     * A file size limit protects the machine against runaway software errors.
+     * It is not suitable to enforce mail quota, because users can get around
+     * mail quota by delivering to /file/name or to |command.
+     * 
+     * We can't have mailbox size limit smaller than the message size limit,
+     * because that prohibits the delivery agent from updating the queue
+     * file.
+     */
+    if (var_mailbox_limit) {
+       if (var_mailbox_limit < var_message_limit)
+           msg_fatal("main.cf configuration error: %s is smaller than %s",
+                     VAR_MAILBOX_LIMIT, VAR_MESSAGE_LIMIT);
+       set_file_limit(var_mailbox_limit);
+    }
+}
+
 /* main - pass control to the single-threaded skeleton */
 
 int     main(int argc, char **argv)
@@ -631,6 +664,7 @@ int     main(int argc, char **argv)
     };
     static CONFIG_INT_TABLE int_table[] = {
        VAR_DUP_FILTER_LIMIT, DEF_DUP_FILTER_LIMIT, &var_dup_filter_limit, 0, 0,
+       VAR_MAILBOX_LIMIT, DEF_MAILBOX_LIMIT, &var_mailbox_limit, 0, 0,
        0,
     };
     static CONFIG_STR_TABLE str_table[] = {
@@ -671,6 +705,7 @@ int     main(int argc, char **argv)
                       MAIL_SERVER_RAW_TABLE, raw_table,
                       MAIL_SERVER_BOOL_TABLE, bool_table,
                       MAIL_SERVER_TIME_TABLE, time_table,
+                      MAIL_SERVER_PRE_INIT, pre_init,
                       MAIL_SERVER_POST_INIT, post_init,
                       MAIL_SERVER_PRE_ACCEPT, pre_accept,
                       0);
index 01adc5b1541eeb7a4bfb801a80671b0b15be389b..e9bd0de85c77905c10da88bd7a9f9fccffbb83d2 100644 (file)
@@ -59,6 +59,7 @@
 
 #include <mail_copy.h>
 #include <bounce.h>
+#include <defer.h>
 #include <sent.h>
 #include <mail_params.h>
 
@@ -152,10 +153,11 @@ int     deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr, char *path)
     set_eugid(var_owner_uid, var_owner_gid);
 
     if (status)
-       bounce_append(BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
-                     "maildir delivery failed: %s", vstring_str(why));
+       status = (errno == ENOSPC ? defer_append : bounce_append)
+           (BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
+            "maildir delivery failed: %s", vstring_str(why));
     else
-       sent(SENT_ATTR(state.msg_attr), "maildir");
+       status = sent(SENT_ATTR(state.msg_attr), "maildir");
     vstring_free(buf);
     vstring_free(why);
     myfree(newdir);
@@ -163,5 +165,5 @@ int     deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr, char *path)
     myfree(curdir);
     myfree(tmpfile);
     myfree(newfile);
-    return (0);
+    return (status);
 }
index 2967d914f8cf03ac1f85152ae2686bda26683b20..c7dead391fb93e6c1133846fecdc8ac42c4cf2d0 100644 (file)
 #include <unistd.h>
 #include <string.h>
 #include <fcntl.h>
+#include <limits.h>
 
 /* Utility library. */
 
@@ -288,11 +289,9 @@ int     main(int argc, char **argv)
     clean_env(import_env->argv);
     argv_free(import_env);
 
-    if ((inherited_limit = get_file_limit()) < (off_t) var_message_limit) {
-       msg_warn("file size limit %lu < message_size_limit %lu -- reset",
-       (unsigned long) inherited_limit, (unsigned long) var_message_limit);
-       set_file_limit(var_message_limit);
-    }
+    if ((inherited_limit = get_file_limit()) < (off_t) INT_MAX)
+       set_file_limit(INT_MAX);
+
     if (chdir(var_queue_dir))
        msg_fatal("chdir %s: %m", var_queue_dir);
 
index 0ad0fa7b16e070b3e3300b9bc26f379c8d313ce5..ca501e91873f678d7bd011844d1cb005a3cdda30 100644 (file)
 
 /* Local stuff. */
 
+#ifdef USE_SIG_PIPE
+#include <errno.h>
+#include <fcntl.h>
+#include <iostuff.h>
+
+int     master_sig_pipe[2];
+
+#define SIG_PIPE_WRITE_FD master_sig_pipe[1]
+#define SIG_PIPE_READ_FD master_sig_pipe[0]
+#endif
+
 int     master_gotsigchld;
 int     master_gotsighup;
 
@@ -99,6 +110,29 @@ static void master_sigchld(int sig, int code, struct sigcontext * scp)
 
 #else
 
+#ifdef USE_SIG_PIPE
+
+/* master_sigchld - force wakeup from select() */
+
+static void master_sigchld(int sig)
+{
+    if (write(SIG_PIPE_WRITE_FD, "", 1) != 1)
+       msg_warn("write to SIG_PIPE_WRITE_FD failed: %m");
+}
+
+/* master_sig_event - called upon return from select() */
+
+static void master_sig_event(int unused_event, char *unused_context)
+{
+    char    c[1];
+
+    while (read(SIG_PIPE_READ_FD, c, 1) > 0)
+        /* void */ ;
+    master_gotsigchld = 1;
+}
+
+#else
+
 static void master_sigchld(int sig)
 {
 
@@ -111,6 +145,7 @@ static void master_sigchld(int sig)
     master_gotsigchld = sig;
 }
 
+#endif
 #endif
 
 /* master_sigdeath - die, women and children first */
@@ -174,6 +209,16 @@ void    master_sigsetup(void)
        if (sigaction(sigs[i], &action, (struct sigaction *) 0) < 0)
            msg_fatal("%s: sigaction(%d): %m", myname, sigs[i]);
 
+#ifdef USE_SIG_PIPE
+    if (pipe(master_sig_pipe))
+       msg_fatal("pipe: %m");
+    non_blocking(SIG_PIPE_WRITE_FD, NON_BLOCKING);
+    non_blocking(SIG_PIPE_READ_FD, NON_BLOCKING);
+    close_on_exec(SIG_PIPE_WRITE_FD, CLOSE_ON_EXEC);
+    close_on_exec(SIG_PIPE_READ_FD, CLOSE_ON_EXEC);
+    event_enable_read(SIG_PIPE_READ_FD, master_sig_event, (char *) 0);
+#endif
+
     /*
      * Intercept SIGHUP (re-read config file) and SIGCHLD (child exit).
      */
index 60c1fb48e828e231a36ae5a48565ed9d55402ccf..ee9154c6df6a303b0b091b87ed6c63a634c68800 100644 (file)
@@ -291,8 +291,6 @@ static int parse_callback(int type, VSTRING *buf, char *context)
            *expand_flag |= PIPE_FLAG_EXTENSION;
        else if (strcmp(vstring_str(buf), PIPE_DICT_MAILBOX) == 0)
            *expand_flag |= PIPE_FLAG_MAILBOX;
-       else if (strcmp(vstring_str(buf), PIPE_DICT_SIZE) == 0)
-           *expand_flag |= PIPE_FLAG_SIZE;
     }
     return (0);
 }
@@ -397,14 +395,6 @@ static ARGV *expand_argv(char **argv, RECIPIENT_LIST *rcpt_list, long data_size)
                    dict_update(PIPE_DICT_TABLE, PIPE_DICT_MAILBOX, STR(buf));
                }
 
-               /*
-                * This argument contains $size.
-                */
-               if (expand_flag & PIPE_FLAG_SIZE) {
-                   vstring_sprintf(buf, "%ld", data_size);
-                   dict_update(PIPE_DICT_TABLE, PIPE_DICT_SIZE, STR(buf));
-               }
-
                /*
                 * Done.
                 */
@@ -698,6 +688,10 @@ static int deliver_message(DELIVER_REQUEST *request, char *service, char **argv)
 
     dict_update(PIPE_DICT_TABLE, PIPE_DICT_SENDER, request->sender);
     dict_update(PIPE_DICT_TABLE, PIPE_DICT_NEXTHOP, request->nexthop);
+    buf = vstring_alloc(10);
+    vstring_sprintf(buf, "%ld", (long) request->data_size);
+    dict_update(PIPE_DICT_TABLE, PIPE_DICT_SIZE, STR(buf));
+    vstring_free(buf);
     expanded_argv = expand_argv(attr.command, rcpt_list, request->data_size);
     export_env = argv_split(var_export_environ, ", \t\r\n");
 
index af5f001c1ee374d6c31a1596901418e9029b0264..1cf46772319c64ddeb584df85514d06d70623878 100644 (file)
@@ -93,11 +93,11 @@ postconf.o: time_vars.h
 postconf.o: bool_vars.h
 postconf.o: int_vars.h
 postconf.o: str_vars.h
-postconf.o: local_vars.h
+postconf.o: raw_vars.h
 postconf.o: smtp_vars.h
 postconf.o: time_table.h
 postconf.o: bool_table.h
 postconf.o: int_table.h
 postconf.o: str_table.h
-postconf.o: local_table.h
 postconf.o: smtp_table.h
+postconf.o: raw_table.h
diff --git a/postfix/src/postconf/local_table.h b/postfix/src/postconf/local_table.h
deleted file mode 100644 (file)
index c612ab7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-    "local_destination_concurrency_limit", "$default_destination_concurrency_limit", &var_local_destination_concurrency_limit, 0, 0,
diff --git a/postfix/src/postconf/local_vars.h b/postfix/src/postconf/local_vars.h
deleted file mode 100644 (file)
index c09dc14..0000000
+++ /dev/null
@@ -1 +0,0 @@
-char   *var_local_destination_concurrency_limit;
index 80b1c2126f16726aa0f9da7cc69c024029e60af6..da7d5625eddaa46b34a956c2a207203a09f4736f 100644 (file)
@@ -130,7 +130,6 @@ DICT   *text_table;
  /*
   * Manually extracted.
   */
-#include "local_vars.h"
 #include "smtp_vars.h"
 
  /*
@@ -153,7 +152,6 @@ static CONFIG_INT_TABLE int_table[] = {
 
 static CONFIG_STR_TABLE str_table[] = {
 #include "str_table.h"
-#include "local_table.h"               /* XXX */
 #include "smtp_table.h"                        /* XXX */
     0,
 };
@@ -253,8 +251,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());
 }
 
@@ -420,7 +430,7 @@ static void set_parameters(void)
      * bool_table, int_table, str_table, and raw_table. Look up each
      * parameter name in the configuration parameter dictionary. If the
      * parameter is not set, take the default value, or take the value from
-     * in main.c, without doing $name expansions. This includes converting
+     * main.cf, without doing $name expansions. This includes converting
      * default values from numeric/boolean internal forms to external string
      * form.
      * 
@@ -658,9 +668,7 @@ static void print_parameter(int mode, char *ptr)
 #define INSIDE(p,t) (ptr >= (char *) t && ptr < ((char *) t) + sizeof(t))
 
     /*
-     * This is gross, but the best we can do on short notice. Instead of
-     * guessing we should use a tagged union. This is what code looks like
-     * when written under the pressure of a first public release.
+     * This is gross, but the best we can do on short notice.
      */
     if (INSIDE(ptr, time_table))
        print_time(mode, (CONFIG_TIME_TABLE *) ptr);
@@ -790,9 +798,6 @@ int     main(int argc, char **argv)
        case 'd':
            mode |= SHOW_DEFS;
            break;
-       case 'E':
-           mode |= SHOW_EVAL;
-           break;
        case 'e':
            mode |= EDIT_MAIN;
            break;
index 4f53c3b07f98e8e4fe65f18bb8bf5bc4e6efd9b1..e525247340b527f97a04985108be7296d265a4a2 100644 (file)
@@ -277,7 +277,7 @@ static void super(char **queues, int action)
     argv_free(hash_queue_names);
 }
 
-main(int argc, char **argv)
+int     main(int argc, char **argv)
 {
     int     fd;
     struct stat st;
index 97488cd63cc858d791f5bbfac5ad6681e2442a5c..7513aa368e9a379d4a21a25aed92f7e9d0c61eee 100644 (file)
@@ -292,6 +292,7 @@ bool    var_allow_min_user;
 int     var_qmgr_fudge;
 int     var_qmgr_hog;
 int     var_local_rcpt_lim;            /* XXX */
+int     var_local_con_lim;             /* XXX */
 
 static QMGR_SCAN *qmgr_incoming;
 static QMGR_SCAN *qmgr_deferred;
@@ -489,6 +490,7 @@ int     main(int argc, char **argv)
        VAR_QMGR_FUDGE, DEF_QMGR_FUDGE, &var_qmgr_fudge, 10, 100,
        VAR_QMGR_HOG, DEF_QMGR_HOG, &var_qmgr_hog, 10, 100,
        VAR_LOCAL_RCPT_LIMIT, DEF_LOCAL_RCPT_LIMIT, &var_local_rcpt_lim, 0, 0,
+       VAR_LOCAL_CON_LIMIT, DEF_LOCAL_CON_LIMIT, &var_local_con_lim, 0, 0,
        0,
     };
     static CONFIG_BOOL_TABLE bool_table[] = {
index e96126266398602a4318a2cddc23fc6e0bc949b0..d6631c0add856c4486dfd145a00d67c9cfa9bdf6 100644 (file)
@@ -55,7 +55,7 @@
 
 /* qmgr_bounce_recipient - bounce one message recipient */
 
-void    qmgr_bounce_recipient(QMGR_MESSAGE *message, QMGR_RCPT * recipient,
+void    qmgr_bounce_recipient(QMGR_MESSAGE *message, QMGR_RCPT *recipient,
                                      const char *format,...)
 {
     va_list ap;
index 003c4373e8125de628ebe83caf2fa7efa29b19e5..1a605dd1f052914f228402b7dc400a91268a85f8 100644 (file)
@@ -121,9 +121,10 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream)
     char   *cp;
 
     /*
-     * With local delivery, the queue name is user@nexthop, so that we can
-     * implement per-recipient concurrency limits. The delivery agent
-     * protocol expects nexthop only.
+     * With mail transports that accept only one recipient per delivery, the
+     * queue name is user@nexthop, so that we can implement per-recipient
+     * concurrency limits. However, the delivery agent protocol expects
+     * nexthop only, so we must strip off the recipient local part.
      */
     mail_print(stream, "%d %s %s %ld %ld %s %s %s %s %ld",
          message->inspect_xport ? DEL_REQ_FLAG_BOUNCE : DEL_REQ_FLAG_DEFLT,
index 6e2fb3b2ef7d066143eee277e43d8f2c4013778c..1d5c3afacf26f3da54e427c29a182bcc136857a9 100644 (file)
@@ -47,7 +47,7 @@
 /*     the queue file to the deferred queue; send bounce reports to the
 /*     message originator (see qmgr_active_done()).
 /*
-/*     qmgr_entry_select() randomly selects one entry from the named
+/*     qmgr_entry_select() selects the next entry from the named
 /*     per-site queue's `todo' list for actual delivery. The entry is
 /*     moved to the queue's `busy' list: the list of messages being
 /*     delivered.
index bd6f74959f6f2e55956d6c28637d30fa644504d0..e696fb4a768133a6d35d0b59a7bcdcea3bfeaf3b 100644 (file)
@@ -461,7 +461,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
         */
        if ((at = strrchr(recipient->address, '@')) != 0
            && (at + 1)[strspn(at + 1, "[]0123456789.")] != 0
-           && valid_hostname(at + 1) == 0) {
+           && valid_hostname(at + 1, DONT_GRIPE) == 0) {
            qmgr_bounce_recipient(message, recipient,
                                  "bad host/domain syntax: \"%s\"", at + 1);
            continue;
@@ -550,8 +550,11 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
 
        /*
         * Queues are identified by the transport name and by the next-hop
-        * hostname. When the destination is local (no next hop), derive the
-        * queue name from the recipient name. XXX Should split the address
+        * hostname. When the delivery agent accepts only one recipient per
+        * delivery, give each recipient its own queue, so that deliveries to
+        * different recipients of the same message can happen in parallel.
+        * This also has the benefit that one bad recipient cannot interfere
+        * with deliveries to other recipients. XXX Should split the address
         * on the recipient delimiter if one is defined, but doing a proper
         * job requires knowledge of local aliases. Yuck! I don't want to
         * duplicate delivery-agent specific knowledge in the queue manager.
@@ -559,26 +562,38 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
         * queue name. Should have separate fields for queue name and for
         * destination.
         */
-       if ((at = strrchr(STR(reply.recipient), '@')) == 0
-           || resolve_local(at + 1)) {
-           len = (at != 0 ? (at - STR(reply.recipient))
-                  : strlen(STR(reply.recipient)));
+       at = strrchr(STR(reply.recipient), '@');
+       len = (at ? (at - STR(reply.recipient)) : strlen(STR(reply.recipient)));
+
+       /*
+        * Look up or instantiate the proper transport. We're working a
+        * little ahead, doing queue management stuff that used to be done
+        * way down.
+        */
+       if (transport == 0 || !STREQ(transport->name, STR(reply.transport))) {
+           if ((transport = qmgr_transport_find(STR(reply.transport))) == 0)
+               transport = qmgr_transport_create(STR(reply.transport));
+           queue = 0;
+       }
+       if (transport->recipient_limit == 1) {
            VSTRING_SPACE(reply.nexthop, len + 1);
            memmove(STR(reply.nexthop) + len + 1, STR(reply.nexthop),
                    LEN(reply.nexthop) + 1);
            memcpy(STR(reply.nexthop), STR(reply.recipient), len);
            STR(reply.nexthop)[len] = '@';
            lowercase(STR(reply.nexthop));
+       }
 
-           /*
-            * Discard mail to the local double bounce address here, so this
-            * system can run without a local delivery agent. They'd still
-            * have to configure something for mail directed to the local
-            * postmaster, though, but that is an RFC requirement anyway.
-            */
+       /*
+        * Discard mail to the local double bounce address here, so this
+        * system can run without a local delivery agent. They'd still have
+        * to configure something for mail directed to the local postmaster,
+        * though, but that is an RFC requirement anyway.
+        */
+       if (at == 0 || resolve_local(at + 1)) {
            if (strncasecmp(STR(reply.recipient), var_double_bounce_sender,
-                           at - STR(reply.recipient)) == 0
-               && !var_double_bounce_sender[at - STR(reply.recipient)]) {
+                           len) == 0
+               && !var_double_bounce_sender[len]) {
                sent(message->queue_id, recipient->address,
                     "none", message->arrival_time, "discarded");
                deliver_completed(message->fp, recipient->offset);
@@ -613,6 +628,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
         * bind each recipient to an in-core queue instance which is needed
         * anyway. That gives all information needed for recipient grouping.
         */
+#if 0
 
        /*
         * Look up or instantiate the proper transport.
@@ -622,6 +638,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
                transport = qmgr_transport_create(STR(reply.transport));
            queue = 0;
        }
+#endif
 
        /*
         * This transport is dead. Defer delivery to this recipient.
index febdc37012c60122a2f7055122121888f4e023cd..e9311ef4a552d59b2a7af921555738659c97fe8f 100644 (file)
@@ -735,7 +735,8 @@ int     main(int argc, char **argv)
      * reset the saved set-userid, which would be a security vulnerability.
      */
     if (geteuid() == 0 && getuid() != 0) {
-       msg_warn("sendmail has set-uid root file permissions, or is run from a set-uid root process");
+       msg_warn("the Postfix sendmail command has set-uid root file permissions");
+       msg_warn("or the command is run from a set-uid root process");
        msg_warn("the Postfix sendmail command must be installed without set-uid root file permissions");
        set_ugid(getuid(), getgid());
     }
@@ -903,7 +904,7 @@ int     main(int argc, char **argv)
        msg_fatal("-t can be used only in delivery mode");
 
     if (site_to_flush && mode != SM_MODE_ENQUEUE)
-       msg_fatal("-t can be used only in delivery mode");
+       msg_fatal("-qR can be used only in delivery mode");
 
     if (extract_recipients && argv[OPTIND])
        msg_fatal("cannot handle command-line recipients with -t");
index 8f97c6b587517d44a68c1399c32ea3726b796723..ed46099b66507f1d8e8cee7af5fbdc155c6f342b 100644 (file)
@@ -162,9 +162,9 @@ smtp_proto.o: ../../include/record.h
 smtp_proto.o: ../../include/rec_type.h
 smtp_proto.o: ../../include/off_cvt.h
 smtp_proto.o: ../../include/mark_corrupt.h
+smtp_proto.o: ../../include/quote_821_local.h
 smtp_proto.o: smtp.h
 smtp_proto.o: ../../include/argv.h
-smtp_proto.o: ../../include/quote_821_local.h
 smtp_proto.o: smtp_sasl.h
 smtp_sasl_glue.o: smtp_sasl_glue.c
 smtp_sasl_glue.o: ../../include/sys_defs.h
index 6bce6f2e974f71ff52b4a5867ddb9590d130999e..477e33b7197b7212ac7687ae29f0ca87485ffc6c 100644 (file)
@@ -360,9 +360,12 @@ static void pre_init(char *unused_name, char **unused_argv)
 {
     debug_peer_init();
 
-#ifdef USE_SASL_AUTH
     if (var_smtp_sasl_enable)
+#ifdef USE_SASL_AUTH
        smtp_sasl_initialize();
+#else
+       msg_warn("%s is true, but SASL support is not compiled in",
+                VAR_SMTP_SASL_ENABLE);
 #endif
 }
 
index 7c06a8e5a49b9021def69988917d6afeb9a5be5f..c9109fa3a4b53644e48811f8878c3800db62e284 100644 (file)
@@ -336,6 +336,11 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why, int *found_myself)
        best_pref = (mx_names ? mx_names->pref : IMPOSSIBLE_PREFERENCE);
        addr_list = smtp_addr_list(mx_names, why);
        dns_rr_free(mx_names);
+       if (addr_list == 0) {
+           smtp_errno = SMTP_RETRY;
+           msg_warn("no MX host for %s has a valid A record", name);
+           break;
+       }
        best_found = (addr_list ? addr_list->pref : IMPOSSIBLE_PREFERENCE);
        if (msg_verbose)
            smtp_print_addr(name, addr_list);
index 2e1625a7fc1de9e7a31a52a239b317051d1e8cba..f3818236520b70b9f9ddc280624be4aae0e4be7d 100644 (file)
@@ -73,7 +73,7 @@
 
 void    smtp_sasl_helo_auth(SMTP_STATE *state, const char *words)
 {
-msg_info("smtp_sasl_helo_auth: words=\"%s\"", words);
+
     /*
      * XXX If the server offers a null list of authentication mechanisms,
      * then pretend that the server doesn't support SASL authentication.
index c0a433e87b3ae95ba3bf2e3954c645f21273f909..90d9aa96bbc293d78bcc3c958864201b7d2a7e3e 100644 (file)
@@ -179,6 +179,7 @@ smtpd_check.o: ../../include/maps.h
 smtpd_check.o: ../../include/mail_addr_find.h
 smtpd_check.o: smtpd.h
 smtpd_check.o: ../../include/mail_stream.h
+smtpd_check.o: smtpd_sasl_glue.h
 smtpd_check.o: smtpd_check.h
 smtpd_peer.o: smtpd_peer.c
 smtpd_peer.o: ../../include/sys_defs.h
index 9df7131819de1b7f04f4419b371f87e5fe860bc0..3de90461a521916b24cbbdb2ddee02727840de80 100644 (file)
@@ -57,9 +57,9 @@
 /* .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.
-/* .IP \fBallow_broken_auth_clients\fR
+/* .IP \fBbroken_sasl_auth_clients\fR
 /*     Support older Microsoft clients that mis-implement the AUTH
-/*      protocol, and that expect an EHLO response of "250 AUTH=list"
+/*     protocol, and that expect an EHLO response of "250 AUTH=list"
 /*     instead of "250 AUTH list".
 /* .SH "Content inspection controls"
 /* .IP \fBcontent_filter\fR
 /*     either bounces mail or re-injects the result back into Postfix.
 /*     This parameter uses the same syntax as the right-hand side of
 /*     a Postfix transport table.
-/* .SH "Authenication controls"
+/* .SH "Authentication controls"
 /* .IP \fBenable_sasl_authentication\fR
 /*     Enable per-session authentication as per RFC 2554 (SASL).
 /*     This functionality is available only when explicitly selected
 /*     at program build time and explicitly enabled at runtime.
+/* .IP \fBsmtpd_sasl_local_domain\fR
+/*     The name of the local authentication realm.
 /* .IP \fBsmtpd_sasl_security_options\fR
 /*     Zero or more of the following.
 /* .RS
@@ -1094,7 +1096,7 @@ static int etrn_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
     }
     if (!ISALNUM(argv[1].strval[0]))
        argv[1].strval++;
-    if (!valid_hostname(argv[1].strval)) {
+    if (!valid_hostname(argv[1].strval, DONT_GRIPE)) {
        state->error_mask |= MAIL_ERROR_PROTOCOL;
        smtpd_chat_reply(state, "501 Error: invalid parameter syntax");
        return (-1);
@@ -1415,9 +1417,12 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
     debug_peer_init();
     msg_cleanup(smtpd_cleanup);
 
-#ifdef USE_SASL_AUTH
     if (var_smtpd_sasl_enable)
+#ifdef USE_SASL_AUTH
        smtpd_sasl_initialize();
+#else
+       msg_warn("%s is true, but SASL support is not compiled in",
+                VAR_SMTPD_SASL_ENABLE);
 #endif
 }
 
index 447ad932ead2298e4c88c3c53521837bad31efaa..29fb3d2d743dd8b0cee2d23d2bd86d29b1691324 100644 (file)
@@ -8,6 +8,11 @@
 /* DESCRIPTION
 /* .nf
 
+ /*
+  * System library.
+  */
+#include <unistd.h>
+
  /*
   * SASL library.
   */
index 3d8c0e1305a48335689b6ed357aab9dd95d62019..32187d3f71cd4dd18ce11280abbe7c55ef8f03bd 100644 (file)
 /* Application-specific. */
 
 #include "smtpd.h"
+#include "smtpd_sasl_glue.h"
 #include "smtpd_check.h"
 
  /*
@@ -636,7 +637,7 @@ static int reject_invalid_hostaddr(SMTPD_STATE *state, char *addr,
     /*
      * Validate the address.
      */
-    if (!valid_hostaddr(test_addr))
+    if (!valid_hostaddr(test_addr, DONT_GRIPE))
        stat = smtpd_check_reject(state, MAIL_ERROR_POLICY,
                                  "%d <%s>: %s rejected: invalid ip address",
                                var_bad_name_code, reply_name, reply_class);
@@ -672,7 +673,7 @@ static int reject_invalid_hostname(SMTPD_STATE *state, char *name,
     /*
      * Validate the hostname.
      */
-    if (!valid_hostname(test_name))
+    if (!valid_hostname(test_name, DONT_GRIPE))
        stat = smtpd_check_reject(state, MAIL_ERROR_POLICY,
                                  "%d <%s>: %s rejected: Invalid name",
                                var_bad_name_code, reply_name, reply_class);
@@ -708,7 +709,7 @@ static int reject_non_fqdn_hostname(SMTPD_STATE *state, char *name,
     /*
      * Validate the hostname.
      */
-    if (!valid_hostname(test_name) || !strchr(test_name, '.'))
+    if (!valid_hostname(test_name, DONT_GRIPE) || !strchr(test_name, '.'))
        stat = smtpd_check_reject(state, MAIL_ERROR_POLICY,
                      "%d <%s>: %s rejected: need fully-qualified hostname",
                                var_non_fqdn_code, reply_name, reply_class);
@@ -1062,7 +1063,7 @@ static int reject_non_fqdn_address(SMTPD_STATE *state, char *addr,
     /*
      * Validate the domain.
      */
-    if (!*test_dom || !valid_hostname(test_dom) || !strchr(test_dom, '.'))
+    if (!*test_dom || !valid_hostname(test_dom, DONT_GRIPE) || !strchr(test_dom, '.'))
        stat = smtpd_check_reject(state, MAIL_ERROR_POLICY,
                       "%d <%s>: %s rejected: need fully-qualified address",
                                var_non_fqdn_code, reply_name, reply_class);
index 42c4b254314cbfc19482e7df5063dfdf074e0472..e6ef0ab3518d1b7cfcbf1b750db19141716b0e6c 100644 (file)
@@ -135,7 +135,7 @@ void    smtpd_peer_init(SMTPD_STATE *state)
        if (hp == 0) {
            state->name = mystrdup("unknown");
            state->peer_code = (h_errno == TRY_AGAIN ? 4 : 5);
-       } else if (!valid_hostname(hp->h_name)) {
+       } else if (!valid_hostname(hp->h_name, DONT_GRIPE)) {
            state->name = mystrdup("unknown");
            state->peer_code = 5;
        } else {
index a4180135440505bfaf4745eedff85e1380f4c503..81aab916b360b249b3fb28f04b2cb1bc39e1f169 100644 (file)
@@ -336,11 +336,16 @@ static void connect_event(int unused_event, char *context)
 
     if ((fd = accept(sock, &sa, &len)) >= 0) {
        if (msg_verbose)
-           msg_info("connect (%s)", sa.sa_family == AF_LOCAL ? "AF_LOCAL" :
+           msg_info("connect (%s)",
+#ifdef AF_LOCAL
+                    sa.sa_family == AF_LOCAL ? "AF_LOCAL" :
+#else
+                    sa.sa_family == AF_UNIX ? "AF_UNIX" :
+#endif
+                    sa.sa_family == AF_INET ? "AF_INET" :
 #ifdef AF_INET6
                     sa.sa_family == AF_INET6 ? "AF_INET6" :
 #endif
-                    sa.sa_family == AF_INET ? "AF_INET" :
                     "unknown protocol family");
        non_blocking(fd, NON_BLOCKING);
        state = (SINK_STATE *) mymalloc(sizeof(*state));
index 35ac25f540ccf7fc13e3cf11e4370bcbc9e68a34..f792599c2162be659fe363be634212d1696d429f 100644 (file)
@@ -22,7 +22,8 @@ SRCS  = argv.c argv_split.c attr.c basename.c binhash.c chroot_uid.c \
        stream_connect.c stream_trigger.c dict_regexp.c mac_expand.c \
        clean_env.c watchdog.c spawn_command.c duplex_pipe.c sane_rename.c \
        sane_link.c unescape.c timed_read.c timed_write.c dict_tcp.c \
-       hex_quote.c 
+       hex_quote.c dict_alloc.c rand_sleep.c sane_time.c dict_debug.c \
+       sane_socketpair.c
 OBJS   = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
        close_on_exec.o concatenate.o dict.o dict_db.o dict_dbm.o \
        dict_env.o dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \
@@ -46,7 +47,8 @@ OBJS  = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
        stream_connect.o stream_trigger.o dict_regexp.o mac_expand.o \
        clean_env.o watchdog.o spawn_command.o duplex_pipe.o sane_rename.o \
        sane_link.o unescape.o timed_read.o timed_write.o dict_tcp.o \
-       hex_quote.o 
+       hex_quote.o dict_alloc.o rand_sleep.o sane_time.o dict_debug.o \
+       sane_socketpair.o
 HDRS   = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
        dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_mysql.h \
        dict_ni.h dict_nis.h dict_nisplus.h dir_forest.h events.h \
@@ -61,7 +63,8 @@ HDRS  = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
        timed_connect.h timed_wait.h trigger.h username.h valid_hostname.h \
        vbuf.h vbuf_print.h vstream.h vstring.h vstring_vstream.h \
        dict_unix.h dict_pcre.h dict_regexp.h mac_expand.h clean_env.h \
-       watchdog.h spawn_command.h sane_fsops.h dict_tcp.h hex_quote.h
+       watchdog.h spawn_command.h sane_fsops.h dict_tcp.h hex_quote.h \
+       sane_time.h sane_socketpair.h
 TESTSRC        = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
        stream_test.c dup2_pass_on_exec.c
 WARN   = -W -Wformat -Wimplicit -Wmissing-prototypes \
@@ -77,7 +80,7 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
        inet_addr_host inet_addr_local mac_parse make_dirs msg_syslog \
        mystrtok sigdelay translit valid_hostname vstream_popen \
        vstring vstring_vstream doze select_bug stream_test mac_expand \
-       watchdog unescape hex_quote name_mask
+       watchdog unescape hex_quote name_mask rand_sleep sane_time
 
 LIB_DIR        = ../../lib
 INC_DIR        = ../../include
@@ -261,6 +264,16 @@ name_mask: $(LIB)
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
+rand_sleep: $(LIB)
+       mv $@.o junk
+       $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
+       mv junk $@.o
+
+sane_time: $(LIB)
+       mv $@.o junk
+       $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
+       mv junk $@.o
+
 depend: $(MAKES)
        (sed '1,/^# do not edit/!d' Makefile.in; \
        set -e; for i in [a-z][a-z0-9]*.c; do \
@@ -368,6 +381,14 @@ dict.o: mac_parse.h
 dict.o: dict.h
 dict.o: argv.h
 dict.o: dict_ht.h
+dict_alloc.o: dict_alloc.c
+dict_alloc.o: sys_defs.h
+dict_alloc.o: msg.h
+dict_alloc.o: mymalloc.h
+dict_alloc.o: dict.h
+dict_alloc.o: vstream.h
+dict_alloc.o: vbuf.h
+dict_alloc.o: argv.h
 dict_db.o: dict_db.c
 dict_db.o: sys_defs.h
 dict_db.o: msg.h
@@ -383,18 +404,14 @@ dict_db.o: argv.h
 dict_db.o: dict_db.h
 dict_dbm.o: dict_dbm.c
 dict_dbm.o: sys_defs.h
-dict_dbm.o: msg.h
-dict_dbm.o: mymalloc.h
-dict_dbm.o: htable.h
-dict_dbm.o: iostuff.h
-dict_dbm.o: vstring.h
-dict_dbm.o: vbuf.h
-dict_dbm.o: myflock.h
-dict_dbm.o: stringops.h
-dict_dbm.o: dict.h
-dict_dbm.o: vstream.h
-dict_dbm.o: argv.h
-dict_dbm.o: dict_dbm.h
+dict_debug.o: dict_debug.c
+dict_debug.o: sys_defs.h
+dict_debug.o: msg.h
+dict_debug.o: mymalloc.h
+dict_debug.o: dict.h
+dict_debug.o: vstream.h
+dict_debug.o: vbuf.h
+dict_debug.o: argv.h
 dict_env.o: dict_env.c
 dict_env.o: sys_defs.h
 dict_env.o: mymalloc.h
@@ -418,14 +435,6 @@ dict_ldap.o: dict_ldap.c
 dict_ldap.o: sys_defs.h
 dict_mysql.o: dict_mysql.c
 dict_mysql.o: sys_defs.h
-dict_mysql.o: dict.h
-dict_mysql.o: vstream.h
-dict_mysql.o: vbuf.h
-dict_mysql.o: argv.h
-dict_mysql.o: msg.h
-dict_mysql.o: mymalloc.h
-dict_mysql.o: dict_mysql.h
-dict_mysql.o: vstring.h
 dict_ni.o: dict_ni.c
 dict_ni.o: sys_defs.h
 dict_nis.o: dict_nis.c
@@ -527,6 +536,7 @@ dup2_pass_on_exec.o: dup2_pass_on_exec.c
 duplex_pipe.o: duplex_pipe.c
 duplex_pipe.o: sys_defs.h
 duplex_pipe.o: iostuff.h
+duplex_pipe.o: sane_socketpair.h
 environ.o: environ.c
 environ.o: sys_defs.h
 events.o: events.c
@@ -792,6 +802,10 @@ printable.o: sys_defs.h
 printable.o: stringops.h
 printable.o: vstring.h
 printable.o: vbuf.h
+rand_sleep.o: rand_sleep.c
+rand_sleep.o: sys_defs.h
+rand_sleep.o: msg.h
+rand_sleep.o: iostuff.h
 read_wait.o: read_wait.c
 read_wait.o: sys_defs.h
 read_wait.o: msg.h
@@ -829,6 +843,14 @@ sane_rename.o: sane_rename.c
 sane_rename.o: sys_defs.h
 sane_rename.o: msg.h
 sane_rename.o: sane_fsops.h
+sane_socketpair.o: sane_socketpair.c
+sane_socketpair.o: sys_defs.h
+sane_socketpair.o: msg.h
+sane_socketpair.o: sane_socketpair.h
+sane_time.o: sane_time.c
+sane_time.o: sys_defs.h
+sane_time.o: msg.h
+sane_time.o: sane_time.h
 scan_dir.o: scan_dir.c
 scan_dir.o: sys_defs.h
 scan_dir.o: msg.h
index 6467441ab5fb9c62b6bbdef302c7aeed66aa35e7..7d07d3be0be538baaaf2805a0af6670db67e68bb 100644 (file)
 /*     dict_sequence() steps throuh the named dictionary and returns
 /*     keys and values in some implementation-defined order. The func
 /*     argument is DICT_SEQ_FUN_FIRST to set the cursor to the first
-/*     entry or DICT_SEQ_FUN_NEXT so select the next entry. The result
+/*     entry or DICT_SEQ_FUN_NEXT to select the next entry. The result
 /*     is owned by the underlying dictionary method. Make a copy if the
 /*     result is to be modified, or if the result is to survive multiple
 /*     dict_sequence() calls.
@@ -277,7 +277,7 @@ void    dict_update(const char *dict_name, const char *member, const char *value
     if ((node = dict_node(dict_name)) == 0) {
        if (dict_unknown_allowed == 0)
            msg_fatal("%s: unknown dictionary: %s", myname, dict_name);
-       dict = dict_ht_open(htable_create(0), myfree);
+       dict = dict_ht_open(dict_name, htable_create(0), myfree);
        dict_register(dict_name, dict);
     } else
        dict = node->dict;
@@ -321,7 +321,7 @@ int     dict_delete(const char *dict_name, const char *member)
     if ((node = dict_node(dict_name)) == 0) {
        if (dict_unknown_allowed == 0)
            msg_fatal("%s: unknown dictionary: %s", myname, dict_name);
-       dict = dict_ht_open(htable_create(0), myfree);
+       dict = dict_ht_open(dict_name, htable_create(0), myfree);
        dict_register(dict_name, dict);
     } else
        dict = node->dict;
@@ -345,7 +345,7 @@ int     dict_sequence(const char *dict_name, const int func,
     if ((node = dict_node(dict_name)) == 0) {
        if (dict_unknown_allowed == 0)
            msg_fatal("%s: unknown dictionary: %s", myname, dict_name);
-       dict = dict_ht_open(htable_create(0), myfree);
+       dict = dict_ht_open(dict_name, htable_create(0), myfree);
        dict_register(dict_name, dict);
     } else
        dict = node->dict;
index c5d2b9162bdceee14671d7364a1ef634406f3c5b..5a669aa096dca5a9039528b49510cad8147ca49f 100644 (file)
@@ -27,6 +27,8 @@
   * structure with private members to maintain internal state.
   */
 typedef struct DICT {
+    char   *type;                      /* for diagnostics */
+    char   *name;                      /* for diagnostics */
     int     flags;                     /* see below */
     const char *(*lookup) (struct DICT *, const char *);
     void    (*update) (struct DICT *, const char *, const char *);
@@ -37,6 +39,12 @@ typedef struct DICT {
     time_t  mtime;                     /* mod time at open */
 } DICT;
 
+extern DICT *dict_alloc(const char *, const char *, int);
+extern void dict_free(DICT *);
+
+extern DICT *dict_debug(DICT *);
+#define DICT_DEBUG(d) ((d)->flags & DICT_FLAG_DEBUG ? dict_debug(d) : (d))
+
 #define DICT_FLAG_DUP_WARN     (1<<0)  /* if file, warn about dups */
 #define DICT_FLAG_DUP_IGNORE   (1<<1)  /* if file, ignore dups */
 #define DICT_FLAG_TRY0NULL     (1<<2)  /* do not append 0 to key/value */
@@ -46,6 +54,7 @@ typedef struct DICT {
 #define DICT_FLAG_LOCK         (1<<6)  /* lock before access */
 #define DICT_FLAG_DUP_REPLACE  (1<<7)  /* if file, replace dups */
 #define DICT_FLAG_SYNC_UPDATE  (1<<8)  /* if file, sync updates */
+#define DICT_FLAG_DEBUG                (1<<9)  /* log access */
 
 extern int dict_unknown_allowed;
 extern int dict_errno;
diff --git a/postfix/src/util/dict_alloc.c b/postfix/src/util/dict_alloc.c
new file mode 100644 (file)
index 0000000..005e47a
--- /dev/null
@@ -0,0 +1,131 @@
+/*++
+/* NAME
+/*     dict_alloc 3
+/* SUMMARY
+/*     dictionary memory manager
+/* SYNOPSIS
+/*     #include <dict.h>
+/*
+/*     DICT    *dict_alloc(dict_type, dict_name, size)
+/*     const char *dict_type;
+/*     const char *dict_name;
+/*     int     size;
+/*
+/*     void    dict_free(dict)
+/*     DICT    *ptr;
+/* DESCRIPTION
+/*     dict_alloc() allocates memory for a dictionary structure of
+/*     \fIsize\fR bytes, initializes all properties to default settings,
+/*     and installs default methods that do not support any operation.
+/*     The caller is supposed to override the default methods with
+/*     ones that it supports.
+/*     The purpose of the default methods is to trap an attempt to
+/*     invoke an unsupported method.
+/*
+/*     dict_free() releases memory and cleans up after dict_alloc().
+/*     It is up to the caller to dispose of any memory that was allocated
+/*     by the caller.
+/*
+/*     Arguments:
+/* .IP dict_type
+/*     The official name for this type of dictionary, as used by
+/*     dict_open(3) etc. This is stored under the \fBtype\fR
+/*     member.
+/* .IP dict_name
+/*     Dictionary name. This is stored as the \fBname\fR member.
+/* .IP size
+/*     The size in bytes of the dictionary subclass structure instance.
+/* SEE ALSO
+/*     dict(3)
+/* DIAGNOSTICS
+/*     Fatal errors: the process invokes a default method.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System libraries. */
+
+#include "sys_defs.h"
+
+/* Utility library. */
+
+#include "msg.h"
+#include "mymalloc.h"
+#include "dict.h"
+
+/* dict_default_lookup - trap unimplemented operation */
+
+static const char *dict_default_lookup(DICT *dict, const char *unused_key)
+{
+    msg_fatal("%s table %s: lookup operation is not supported",
+             dict->type, dict->name);
+}
+
+/* dict_default_update - trap unimplemented operation */
+
+static void dict_default_update(DICT *dict, const char *unused_key,
+                                       const char *unused_value)
+{
+    msg_fatal("%s table %s: update operation is not supported",
+             dict->type, dict->name);
+}
+
+/* dict_default_delete - trap unimplemented operation */
+
+static int dict_default_delete(DICT *dict, const char *unused_key)
+{
+    msg_fatal("%s table %s: delete operation is not supported",
+             dict->type, dict->name);
+}
+
+/* dict_default_sequence - trap unimplemented operation */
+
+static int dict_default_sequence(DICT *dict, int function,
+                        const char **unused_key, const char **unused_value)
+{
+    msg_fatal("%s table %s: sequence operation is not supported",
+             dict->type, dict->name);
+}
+
+/* dict_default_close - trap unimplemented operation */
+
+static void dict_default_close(DICT *dict)
+{
+    msg_fatal("%s table %s: close operation is not supported",
+              dict->type, dict->name);
+}
+
+/* dict_alloc - allocate dictionary object, initialize super-class */
+
+DICT   *dict_alloc(const char *dict_type, const char *dict_name, int size)
+{
+    DICT   *dict = (DICT *) mymalloc(size);
+
+    dict->type = mystrdup(dict_type);
+    dict->name = mystrdup(dict_name);
+    dict->flags = DICT_FLAG_FIXED;
+    dict->lookup = dict_default_lookup;
+    dict->update = dict_default_update;
+    dict->delete = dict_default_delete;
+    dict->sequence = dict_default_sequence;
+    dict->close = dict_default_close;
+    dict->fd = -1;
+    dict->mtime = 0;
+    return dict;
+}
+
+/* dict_free - super-class destructor */
+
+void    dict_free(DICT *dict)
+{
+    myfree(dict->type);
+    myfree(dict->name);
+    myfree((char *) dict);
+}
index c75fb077892ae14cc3a62c103c642fae456bc7f9..02b72baf47aee50ef2aeaf249f968089c3b93b12 100644 (file)
 typedef struct {
     DICT    dict;                      /* generic members */
     DB     *db;                                /* open db file */
-    char   *path;                      /* pathname */
 } DICT_DB;
 
 #define DICT_DB_CACHE_SIZE     (1024 * 1024)
@@ -160,7 +159,7 @@ static const char *dict_db_lookup(DICT *dict, const char *name)
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
-       msg_fatal("%s: lock dictionary: %m", dict_db->path);
+       msg_fatal("%s: lock dictionary: %m", dict_db->dict.name);
 
     /*
      * See if this DB file was written with one null byte appended to key and
@@ -170,7 +169,7 @@ static const char *dict_db_lookup(DICT *dict, const char *name)
        db_key.data = (void *) name;
        db_key.size = strlen(name) + 1;
        if ((status = DICT_DB_GET(db, &db_key, &db_value, 0)) < 0)
-           msg_fatal("error reading %s: %m", dict_db->path);
+           msg_fatal("error reading %s: %m", dict_db->dict.name);
        if (status == 0) {
            dict->flags &= ~DICT_FLAG_TRY0NULL;
            result = db_value.data;
@@ -185,7 +184,7 @@ static const char *dict_db_lookup(DICT *dict, const char *name)
        db_key.data = (void *) name;
        db_key.size = strlen(name);
        if ((status = DICT_DB_GET(db, &db_key, &db_value, 0)) < 0)
-           msg_fatal("error reading %s: %m", dict_db->path);
+           msg_fatal("error reading %s: %m", dict_db->dict.name);
        if (status == 0) {
            if (buf == 0)
                buf = vstring_alloc(10);
@@ -200,7 +199,7 @@ static const char *dict_db_lookup(DICT *dict, const char *name)
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
-       msg_fatal("%s: unlock dictionary: %m", dict_db->path);
+       msg_fatal("%s: unlock dictionary: %m", dict_db->dict.name);
 
     return (result);
 }
@@ -248,32 +247,32 @@ static void dict_db_update(DICT *dict, const char *name, const char *value)
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
-       msg_fatal("%s: lock dictionary: %m", dict_db->path);
+       msg_fatal("%s: lock dictionary: %m", dict_db->dict.name);
 
     /*
      * Do the update.
      */
     if ((status = DICT_DB_PUT(db, &db_key, &db_value,
             (dict->flags & DICT_FLAG_DUP_REPLACE) ? 0 : DONT_CLOBBER)) < 0)
-       msg_fatal("error writing %s: %m", dict_db->path);
+       msg_fatal("error writing %s: %m", dict_db->dict.name);
     if (status) {
        if (dict->flags & DICT_FLAG_DUP_IGNORE)
             /* void */ ;
        else if (dict->flags & DICT_FLAG_DUP_WARN)
-           msg_warn("%s: duplicate entry: \"%s\"", dict_db->path, name);
+           msg_warn("%s: duplicate entry: \"%s\"", dict_db->dict.name, name);
        else
-           msg_fatal("%s: duplicate entry: \"%s\"", dict_db->path, name);
+           msg_fatal("%s: duplicate entry: \"%s\"", dict_db->dict.name, name);
     }
     if (dict->flags & DICT_FLAG_SYNC_UPDATE)
        if (DICT_DB_SYNC(db, 0) < 0)
-           msg_fatal("%s: flush dictionary: %m", dict_db->path);
+           msg_fatal("%s: flush dictionary: %m", dict_db->dict.name);
 
     /*
      * Release the exclusive lock.
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
-       msg_fatal("%s: unlock dictionary: %m", dict_db->path);
+       msg_fatal("%s: unlock dictionary: %m", dict_db->dict.name);
 }
 
 /* delete one entry from the dictionary */
@@ -291,7 +290,7 @@ static int dict_db_delete(DICT *dict, const char *name)
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
-       msg_fatal("%s: lock dictionary: %m", dict_db->path);
+       msg_fatal("%s: lock dictionary: %m", dict_db->dict.name);
 
     /*
      * See if this DB file was written with one null byte appended to key and
@@ -301,7 +300,7 @@ static int dict_db_delete(DICT *dict, const char *name)
        db_key.data = (void *) name;
        db_key.size = strlen(name) + 1;
        if ((status = DICT_DB_DEL(db, &db_key, flags)) < 0)
-           msg_fatal("error deleting from %s: %m", dict_db->path);
+           msg_fatal("error deleting from %s: %m", dict_db->dict.name);
        if (status == 0)
            dict->flags &= ~DICT_FLAG_TRY0NULL;
     }
@@ -314,20 +313,20 @@ static int dict_db_delete(DICT *dict, const char *name)
        db_key.data = (void *) name;
        db_key.size = strlen(name);
        if ((status = DICT_DB_DEL(db, &db_key, flags)) < 0)
-           msg_fatal("error deleting from %s: %m", dict_db->path);
+           msg_fatal("error deleting from %s: %m", dict_db->dict.name);
        if (status == 0)
            dict->flags &= ~DICT_FLAG_TRY1NULL;
     }
     if (dict->flags & DICT_FLAG_SYNC_UPDATE)
        if (DICT_DB_SYNC(db, 0) < 0)
-           msg_fatal("%s: flush dictionary: %m", dict_db->path);
+           msg_fatal("%s: flush dictionary: %m", dict_db->dict.name);
 
     /*
      * Release the exclusive lock.
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
-       msg_fatal("%s: unlock dictionary: %m", dict_db->path);
+       msg_fatal("%s: unlock dictionary: %m", dict_db->dict.name);
 
     return status;
 }
@@ -369,17 +368,17 @@ static int dict_db_sequence(DICT *dict, const int function,
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
-       msg_fatal("%s: lock dictionary: %m", dict_db->path);
+       msg_fatal("%s: lock dictionary: %m", dict_db->dict.name);
 
     if ((status = db->seq(db, &db_key, &db_value, db_function)) < 0)
-       msg_fatal("error seeking %s: %m", dict_db->path);
+       msg_fatal("error seeking %s: %m", dict_db->dict.name);
 
     /*
      * Release the exclusive lock.
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
-       msg_fatal("%s: unlock dictionary: %m", dict_db->path);
+       msg_fatal("%s: unlock dictionary: %m", dict_db->dict.name);
 
     if (status == 0) {
 
@@ -415,17 +414,16 @@ static void dict_db_close(DICT *dict)
     DICT_DB *dict_db = (DICT_DB *) dict;
 
     if (DICT_DB_SYNC(dict_db->db, 0) < 0)
-       msg_fatal("flush database %s: %m", dict_db->path);
+       msg_fatal("flush database %s: %m", dict_db->dict.name);
     if (DICT_DB_CLOSE(dict_db->db) < 0)
-       msg_fatal("close database %s: %m", dict_db->path);
-    myfree(dict_db->path);
-    myfree((char *) dict_db);
+       msg_fatal("close database %s: %m", dict_db->dict.name);
+    dict_free(dict);
 }
 
 /* dict_db_open - open data base */
 
-static DICT *dict_db_open(const char *path, int open_flags, int type,
-                                 void *tweak, int dict_flags)
+static DICT *dict_db_open(const char *class, const char *path, int open_flags,
+                                 int type, void *tweak, int dict_flags)
 {
     DICT_DB *dict_db;
     struct stat st;
@@ -509,7 +507,7 @@ static DICT *dict_db_open(const char *path, int open_flags, int type,
        if (close(lock_fd) < 0)
            msg_fatal("close database %s: %m", db_path);
     }
-    dict_db = (DICT_DB *) mymalloc(sizeof(*dict_db));
+    dict_db = (DICT_DB *) dict_alloc(class, db_path, sizeof(*dict_db));
     dict_db->dict.lookup = dict_db_lookup;
     dict_db->dict.update = dict_db_update;
     dict_db->dict.delete = dict_db_delete;
@@ -524,8 +522,8 @@ static DICT *dict_db_open(const char *path, int open_flags, int type,
     if ((dict_flags & (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL)) == 0)
        dict_db->dict.flags |= (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL);
     dict_db->db = db;
-    dict_db->path = db_path;
-    return (&dict_db->dict);
+    myfree(db_path);
+    return (DICT_DEBUG(&dict_db->dict));
 }
 
 /* dict_hash_open - create association with data base */
@@ -551,7 +549,8 @@ DICT   *dict_hash_open(const char *path, int open_flags, int dict_flags)
 
     tweak = 0;
 #endif
-    return (dict_db_open(path, open_flags, DB_HASH, (void *) &tweak, dict_flags));
+    return (dict_db_open(DICT_TYPE_HASH, path, open_flags, DB_HASH,
+                        (void *) &tweak, dict_flags));
 }
 
 /* dict_btree_open - create association with data base */
@@ -576,7 +575,8 @@ DICT   *dict_btree_open(const char *path, int open_flags, int dict_flags)
     tweak = 0;
 #endif
 
-    return (dict_db_open(path, open_flags, DB_BTREE, (void *) &tweak, dict_flags));
+    return (dict_db_open(DICT_TYPE_BTREE, path, open_flags, DB_BTREE,
+                        (void *) &tweak, dict_flags));
 }
 
 #endif
index 43d7e35ab57b50cd56a48e4cd8477b33d73d7faf..f42984ffcb8d19f3803e40e33ad7f1b2135f84fe 100644 (file)
@@ -19,6 +19,9 @@
  /*
   * External interface.
   */
+#define DICT_TYPE_HASH "hash"
+#define DICT_TYPE_BTREE        "btree"
+
 extern DICT *dict_hash_open(const char *, int, int);
 extern DICT *dict_btree_open(const char *, int, int);
 
index c870f32a9bbb96266eedcbd64484c1050351a774..6f3a5611ad73a348a07b1e4bab71f1594fe95d2d 100644 (file)
@@ -66,7 +66,6 @@
 typedef struct {
     DICT    dict;                      /* generic members */
     DBM    *dbm;                       /* open database */
-    char   *path;                      /* pathname */
 } DICT_DBM;
 
 /* dict_dbm_lookup - find database entry */
@@ -86,7 +85,7 @@ static const char *dict_dbm_lookup(DICT *dict, const char *name)
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
-       msg_fatal("%s: lock dictionary: %m", dict_dbm->path);
+       msg_fatal("%s: lock dictionary: %m", dict_dbm->dict.name);
 
     /*
      * See if this DBM file was written with one null byte appended to key
@@ -124,7 +123,7 @@ static const char *dict_dbm_lookup(DICT *dict, const char *name)
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
-       msg_fatal("%s: unlock dictionary: %m", dict_dbm->path);
+       msg_fatal("%s: unlock dictionary: %m", dict_dbm->dict.name);
 
     return (result);
 }
@@ -169,21 +168,21 @@ static void dict_dbm_update(DICT *dict, const char *name, const char *value)
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
-       msg_fatal("%s: lock dictionary: %m", dict_dbm->path);
+       msg_fatal("%s: lock dictionary: %m", dict_dbm->dict.name);
 
     /*
      * Do the update.
      */
     if ((status = dbm_store(dict_dbm->dbm, dbm_key, dbm_value,
      (dict->flags & DICT_FLAG_DUP_REPLACE) ? DBM_REPLACE : DBM_INSERT)) < 0)
-       msg_fatal("error writing DBM database %s: %m", dict_dbm->path);
+       msg_fatal("error writing DBM database %s: %m", dict_dbm->dict.name);
     if (status) {
        if (dict->flags & DICT_FLAG_DUP_IGNORE)
             /* void */ ;
        else if (dict->flags & DICT_FLAG_DUP_WARN)
-           msg_warn("%s: duplicate entry: \"%s\"", dict_dbm->path, name);
+           msg_warn("%s: duplicate entry: \"%s\"", dict_dbm->dict.name, name);
        else
-           msg_fatal("%s: duplicate entry: \"%s\"", dict_dbm->path, name);
+           msg_fatal("%s: duplicate entry: \"%s\"", dict_dbm->dict.name, name);
     }
 
     /*
@@ -191,7 +190,7 @@ static void dict_dbm_update(DICT *dict, const char *name, const char *value)
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
-       msg_fatal("%s: unlock dictionary: %m", dict_dbm->path);
+       msg_fatal("%s: unlock dictionary: %m", dict_dbm->dict.name);
 }
 
 /* dict_dbm_delete - delete one entry from the dictionary */
@@ -208,7 +207,7 @@ static int dict_dbm_delete(DICT *dict, const char *name)
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
-       msg_fatal("%s: lock dictionary: %m", dict_dbm->path);
+       msg_fatal("%s: lock dictionary: %m", dict_dbm->dict.name);
 
     /*
      * See if this DBM file was written with one null byte appended to key
@@ -220,7 +219,7 @@ static int dict_dbm_delete(DICT *dict, const char *name)
        dbm_clearerr(dict_dbm->dbm);
        if ((status = dbm_delete(dict_dbm->dbm, dbm_key)) < 0) {
            if (dbm_error(dict_dbm->dbm) != 0)  /* fatal error */
-               msg_fatal("error deleting from %s: %m", dict_dbm->path);
+               msg_fatal("error deleting from %s: %m", dict_dbm->dict.name);
            status = 1;                         /* not found */
        } else {
            dict->flags &= ~DICT_FLAG_TRY0NULL; /* found */
@@ -237,7 +236,7 @@ static int dict_dbm_delete(DICT *dict, const char *name)
        dbm_clearerr(dict_dbm->dbm);
        if ((status = dbm_delete(dict_dbm->dbm, dbm_key)) < 0) {
            if (dbm_error(dict_dbm->dbm) != 0)  /* fatal error */
-               msg_fatal("error deleting from %s: %m", dict_dbm->path);
+               msg_fatal("error deleting from %s: %m", dict_dbm->dict.name);
            status = 1;                         /* not found */
        } else {
            dict->flags &= ~DICT_FLAG_TRY1NULL; /* found */
@@ -249,7 +248,7 @@ static int dict_dbm_delete(DICT *dict, const char *name)
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
-       msg_fatal("%s: unlock dictionary: %m", dict_dbm->path);
+       msg_fatal("%s: unlock dictionary: %m", dict_dbm->dict.name);
 
     return (status);
 }
@@ -272,7 +271,7 @@ static int dict_dbm_sequence(DICT *dict, const int function,
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
-       msg_fatal("%s: lock dictionary: %m", dict_dbm->path);
+       msg_fatal("%s: lock dictionary: %m", dict_dbm->dict.name);
 
     /*
      * Determine and execute the seek function. It returns the key.
@@ -293,7 +292,7 @@ static int dict_dbm_sequence(DICT *dict, const int function,
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
-       msg_fatal("%s: unlock dictionary: %m", dict_dbm->path);
+       msg_fatal("%s: unlock dictionary: %m", dict_dbm->dict.name);
 
     if (dbm_key.dptr != 0 && dbm_key.dsize > 0) {
 
@@ -336,7 +335,7 @@ static int dict_dbm_sequence(DICT *dict, const int function,
             * condition.
             */
            if (dbm_error(dict_dbm->dbm))
-               msg_fatal("error seeking %s: %m", dict_dbm->path);
+               msg_fatal("error seeking %s: %m", dict_dbm->dict.name);
            return (1);                         /* no error: eof/not found
                                                 * (should not happen!) */
        }
@@ -346,7 +345,7 @@ static int dict_dbm_sequence(DICT *dict, const int function,
         * Determine if we have hit the last record or an error condition.
         */
        if (dbm_error(dict_dbm->dbm))
-           msg_fatal("error seeking %s: %m", dict_dbm->path);
+           msg_fatal("error seeking %s: %m", dict_dbm->dict.name);
        return (1);                             /* no error: eof/not found */
     }
     return (0);
@@ -359,8 +358,7 @@ static void dict_dbm_close(DICT *dict)
     DICT_DBM *dict_dbm = (DICT_DBM *) dict;
 
     dbm_close(dict_dbm->dbm);
-    myfree(dict_dbm->path);
-    myfree((char *) dict_dbm);
+    dict_free(dict);
 }
 
 /* dict_dbm_open - open DBM data base */
@@ -394,7 +392,7 @@ DICT   *dict_dbm_open(const char *path, int open_flags, int dict_flags)
            msg_fatal("close database %s: %m", dbm_path);
        myfree(dbm_path);
     }
-    dict_dbm = (DICT_DBM *) mymalloc(sizeof(*dict_dbm));
+    dict_dbm = (DICT_DBM *) dict_alloc(DICT_TYPE_DBM, path, sizeof(*dict_dbm));
     dict_dbm->dict.lookup = dict_dbm_lookup;
     dict_dbm->dict.update = dict_dbm_update;
     dict_dbm->dict.delete = dict_dbm_delete;
@@ -410,9 +408,8 @@ DICT   *dict_dbm_open(const char *path, int open_flags, int dict_flags)
     if ((dict_flags & (DICT_FLAG_TRY0NULL | DICT_FLAG_TRY1NULL)) == 0)
        dict_dbm->dict.flags |= (DICT_FLAG_TRY0NULL | DICT_FLAG_TRY1NULL);
     dict_dbm->dbm = dbm;
-    dict_dbm->path = mystrdup(path);
 
-    return (&dict_dbm->dict);
+    return (DICT_DEBUG(&dict_dbm->dict));
 }
 
 #endif
index e15e8fb7239546ba7b6ca2b76ab1d93fa948b212..0e2a3347e5a191f72774f924f3235957957de697 100644 (file)
@@ -19,6 +19,8 @@
  /*
   * External interface.
   */
+#define DICT_TYPE_DBM  "dbm"
+
 extern DICT *dict_dbm_open(const char *, int, int);
 
 /* LICENSE
diff --git a/postfix/src/util/dict_debug.c b/postfix/src/util/dict_debug.c
new file mode 100644 (file)
index 0000000..9b85f1e
--- /dev/null
@@ -0,0 +1,134 @@
+/*++
+/* NAME
+/*     dict_debug 3
+/* SUMMARY
+/*     dictionary manager, logging proxy
+/* SYNOPSIS
+/*     #include <dict.h>
+/*
+/*     DICT    *dict_debug(dict_handle)
+/*     DICT    *dict_handle;
+/*
+/*     DICT    *DICT_DEBUG(dict_handle)
+/*     DICT    *dict_handle;
+/* DESCRIPTION
+/*     dict_debug() encapsulates the given dictionary object and returns
+/*     a proxy object that logs all access to the encapsulated object.
+/*     This is more convenient than having to add logging capability
+/*     to each individual dictionary access method.
+/*
+/*     DICT_DEBUG() is an unsafe macro that returns the original object if
+/*     the object's debugging flag is not set, and that otherwise encapsulates
+/*     the object with dict_debug(). This macro simplifies usage by avoiding
+/*     clumsy expressions. The macro evaluates its argument multiple times.
+/* DIAGNOSTICS
+/*     Fatal errors: out of memory.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System libraries. */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <dict.h>
+
+/* Application-specific. */
+
+typedef struct {
+    DICT    dict;                      /* the proxy service */
+    DICT   *real_dict;                 /* encapsulated object */
+} DICT_DEBUG;
+
+/* dict_debug_lookup - log lookup operation */
+
+static const char *dict_debug_lookup(DICT *dict, const char *key)
+{
+    DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
+    const char *result;
+
+    result = dict_get(dict_debug->real_dict, key);
+    msg_info("%s:%s lookup: \"%s\" = \"%s\"", dict->type, dict->name, key,
+            result ? result : dict_errno ? "try again" : "not_found");
+    return (result);
+}
+
+/* dict_debug_update - log update operation */
+
+static void dict_debug_update(DICT *dict, const char *key, const char *value)
+{
+    DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
+
+    msg_info("%s:%s update: \"%s\" = \"%s\"", dict->type, dict->name,
+            key, value);
+    dict_put(dict_debug->real_dict, key, value);
+}
+
+/* dict_debug_delete - log delete operation */
+
+static int dict_debug_delete(DICT *dict, const char *key)
+{
+    DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
+    int     result;
+
+    result = dict_del(dict_debug->real_dict, key);
+    msg_info("%s:%s delete: \"%s\" = \"%s\"", dict->type, dict->name, key,
+            result ? "failed" : "success");
+    return (result);
+}
+
+/* dict_debug_sequence - log sequence operation */
+
+static int dict_debug_sequence(DICT *dict, int function,
+                                      const char **key, const char **value)
+{
+    DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
+    int     result;
+
+    result = dict_seq(dict_debug->real_dict, function, key, value);
+    if (result == 0)
+       msg_info("%s:%s sequence: \"%s\" = \"%s\"", dict->type, dict->name,
+                *key, *value);
+    else
+       msg_info("%s:%s sequence: found EOF", dict->type, dict->name);
+    return (result);
+}
+
+/* dict_debug_close - log operation */
+
+static void dict_debug_close(DICT *dict)
+{
+    DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
+
+    dict_close(dict_debug->real_dict);
+    dict_free(dict);
+}
+
+/* dict_debug - encapsulate dictionary object and install proxies */
+
+DICT   *dict_debug(DICT *real_dict)
+{
+    DICT_DEBUG *dict_debug;
+
+    dict_debug = (DICT_DEBUG *) dict_alloc(real_dict->type,
+                                     real_dict->name, sizeof(*dict_debug));
+    dict_debug->dict.flags = real_dict->flags; /* XXX not synchronized */
+    dict_debug->dict.lookup = dict_debug_lookup;
+    dict_debug->dict.update = dict_debug_update;
+    dict_debug->dict.delete = dict_debug_delete;
+    dict_debug->dict.sequence = dict_debug_sequence;
+    dict_debug->dict.close = dict_debug_close;
+    dict_debug->real_dict = real_dict;
+    return (&dict_debug->dict);
+}
index 1f906c7d75c9b2470c79ba3ea4dce92b8a34c12d..e87ac15a93d60a0d605820e96f52479d01fd658d 100644 (file)
@@ -66,20 +66,19 @@ static const char *dict_env_lookup(DICT *unused_dict, const char *name)
 
 static void dict_env_close(DICT *dict)
 {
-    myfree((char *) dict);
+    dict_free(dict);
 }
 
 /* dict_env_open - make association with environment array */
 
-DICT   *dict_env_open(const char *unused_name, int unused_flags, int dict_flags)
+DICT   *dict_env_open(const char *name, int unused_flags, int dict_flags)
 {
     DICT   *dict;
 
-    dict = (DICT *) mymalloc(sizeof(*dict));
+    dict = dict_alloc(DICT_TYPE_ENVIRON, name, sizeof(*dict));
     dict->lookup = dict_env_lookup;
     dict->update = dict_env_update;
     dict->close = dict_env_close;
     dict->flags = dict_flags | DICT_FLAG_FIXED;
-    dict->fd = -1;
-    return (dict);
+    return (DICT_DEBUG(dict));
 }
index f49e10551ad4420713e7063aa3401725149eac24..9abfa4fa1ac178e194c403c3b3d3699e82d8efc9 100644 (file)
@@ -19,6 +19,8 @@
  /*
   * External interface.
   */
+#define DICT_TYPE_ENVIRON      "environ"
+
 extern DICT *dict_env_open(const char *, int, int);
 
 /* LICENSE
index a3f51e6f3182902f681204620f9add06c0cb9efc..38625daadc4bac29b077d9f00b45b9ad3964d0ef 100644 (file)
@@ -6,7 +6,8 @@
 /* SYNOPSIS
 /*     #include <dict_ht.h>
 /*
-/*     DICT    *dict_ht_open(table, remove)
+/*     DICT    *dict_ht_open(name, table, remove)
+/*     const char *name;
 /*     HTABLE  *table;
 /*     void    (*remove)(char *value)
 /* DESCRIPTION
@@ -82,20 +83,19 @@ static void dict_ht_close(DICT *dict)
 
     if (dict_ht->remove)
        htable_free(dict_ht->table, dict_ht->remove);
-    myfree((char *) dict);
+    dict_free(dict);
 }
 
 /* dict_ht_open - create association with hash table */
 
-DICT   *dict_ht_open(HTABLE *table, void (*remove) (char *))
+DICT   *dict_ht_open(const char *name, HTABLE *table, void (*remove) (char *))
 {
     DICT_HT *dict_ht;
 
-    dict_ht = (DICT_HT *) mymalloc(sizeof(*dict_ht));
+    dict_ht = (DICT_HT *) dict_alloc(DICT_TYPE_HT, name, sizeof(*dict_ht));
     dict_ht->dict.lookup = dict_ht_lookup;
     dict_ht->dict.update = dict_ht_update;
     dict_ht->dict.close = dict_ht_close;
-    dict_ht->dict.fd = -1;
     dict_ht->table = table;
     dict_ht->remove = remove;
     return (&dict_ht->dict);
index 4f408bc97f73fca03e4d6629ea1ee8ed73829bc8..c0b49654e12bb9ab3583db94652704431cd9a4a4 100644 (file)
@@ -20,7 +20,9 @@
  /*
   * External interface.
   */
-extern DICT *dict_ht_open(HTABLE *, void (*) (char *));
+#define DICT_TYPE_HT   "internal"
+
+extern DICT *dict_ht_open(const char *, HTABLE *, void (*) (char *));
 
 /* LICENSE
 /* .ad
index 0ebdd377b410c5b7cd2d5e7711f53f3f91b79bc3..e39fed3fb4b1ebc2a838d809f0c039e8dd8f4bb0 100644 (file)
@@ -92,6 +92,7 @@
 #include <stdlib.h>
 #include <lber.h>
 #include <ldap.h>
+#include <string.h>
 
 /* Utility library. */
 
@@ -383,13 +384,16 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
      * load on the LDAP server.
      */
     if (dict_ldap->domain) {
-       if (strrchr(name, '@') != 0) {
-           if (match_list_match(dict_ldap->domain, (char *) strrchr(name, '@') + 1) == 0) {
-               if (msg_verbose)
-                   msg_info("%s: domain of %s not found in domain list", myname,
-                            name);
-               return (0);
-           }
+       char *p=strrchr(name,'@');
+       if (p != 0)
+           p=p+1;
+       else
+           p=name;
+       if (match_list_match(dict_ldap->domain, p) == 0) {
+           if (msg_verbose)
+               msg_info("%s: domain of %s not found in domain list", myname,
+                        name);
+           return (0);
        }
     }
 
@@ -582,14 +586,6 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
     return (VSTRING_LEN(result) > 0 && !dict_errno ? vstring_str(result) : 0);
 }
 
-/* dict_ldap_update - add or update database entry */
-
-static void dict_ldap_update(DICT *dict, const char *unused_name,
-                                    const char *unused_value)
-{
-    msg_fatal("dict_ldap_update: Operation not implemented");
-}
-
 /* dict_ldap_close - disassociate from data base */
 
 static void dict_ldap_close(DICT *dict)
@@ -608,7 +604,7 @@ static void dict_ldap_close(DICT *dict)
     argv_free(dict_ldap->result_attributes);
     myfree(dict_ldap->bind_dn);
     myfree(dict_ldap->bind_pw);
-    myfree((char *) dict_ldap);
+    dict_free(dict);
 }
 
 /* dict_ldap_open - create association with data base */
@@ -622,11 +618,10 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
     char   *scope;
     char   *attr;
 
-    dict_ldap = (DICT_LDAP *) mymalloc(sizeof(*dict_ldap));
+    dict_ldap = (DICT_LDAP *) dict_alloc(DICT_TYPE_LDAP, ldapsource,
+                                        sizeof(*dict_ldap));
     dict_ldap->dict.lookup = dict_ldap_lookup;
-    dict_ldap->dict.update = dict_ldap_update;
     dict_ldap->dict.close = dict_ldap_close;
-    dict_ldap->dict.fd = -1;
     dict_ldap->dict.flags = dict_flags | DICT_FLAG_FIXED;
 
     if (msg_verbose)
@@ -847,7 +842,7 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
     /*
      * Otherwise, we're all set. Return the new dict_ldap structure.
      */
-    return (&dict_ldap->dict);
+    return (DICT_DEBUG(&dict_ldap->dict));
 }
 
 #endif
index 818835df02cb3986fcbd82966bfeb5bb127463e6..902896351c6135771f7bbb0ffc607d11f90954de 100644 (file)
@@ -19,6 +19,8 @@
  /*
   * External interface.
   */
+#define DICT_TYPE_LDAP "ldap"
+
 extern DICT *dict_ldap_open(const char *, int, int);
 
 /* AUTHOR(S)
index c4e5b5e15d7026a215c1fda600221885e7dc786f..d16c90c85bef0c57b5f6b71f1bf1b9fecfb19c7d 100644 (file)
@@ -73,6 +73,7 @@
 #include <stdlib.h>
 #include <syslog.h>
 #include <time.h>
+#include <mysql.h>
 
 /* Utility library. */
 #include "dict.h"
@@ -84,9 +85,6 @@
 #include "split_at.h"
 #include "find_inet.h"
 
-/* external declarations */
-extern int dict_errno;
-
 /* need some structs to help organize things */
 typedef struct {
     MYSQL  *db;
@@ -120,6 +118,11 @@ typedef struct {
     MYSQL_NAME *name;
 } DICT_MYSQL;
 
+#define STATACTIVE 0
+#define STATFAIL 1
+#define STATUNTRIED 2
+#define RETRY_CONN_INTV 60             /* 1 minute */
+
 /* internal function declarations */
 static PLMYSQL *plmysql_init(char *hostnames[], int);
 static MYSQL_RES *plmysql_query(PLMYSQL *, const char *, char *, char *, char *);
@@ -127,9 +130,6 @@ static void plmysql_dealloc(PLMYSQL *);
 static void plmysql_down_host(HOST *);
 static void plmysql_connect_single(HOST *, char *, char *, char *);
 static int plmysql_ready_reconn(HOST *);
-static void dict_mysql_update(DICT *, const char *, const char *);
-static void dict_mysql_delete(DICT *, const char *);
-static void dict_mysql_sequence(DICT *, const int, const char **, const char **);
 static const char *dict_mysql_lookup(DICT *, const char *);
 DICT   *dict_mysql_open(const char *, int, int);
 static void dict_mysql_close(DICT *);
@@ -344,26 +344,23 @@ static void plmysql_down_host(HOST *host)
  *    parse the map's config file
  *    allocate memory
  **********************************************************************/
-DICT   *dict_mysql_open(const char *name, int unused_flags, int unused_dict_flags)
+DICT   *dict_mysql_open(const char *name, int unused_open_flags, int dict_flags)
 {
     DICT_MYSQL *dict_mysql;
     int     connections;
 
-    dict_mysql = (DICT_MYSQL *) mymalloc(sizeof(DICT_MYSQL));
+    dict_mysql = (DICT_MYSQL *) dict_alloc(DICT_TYPE_MYSQL, name,
+                                          sizeof(DICT_MYSQL));
     dict_mysql->dict.lookup = dict_mysql_lookup;
-    dict_mysql->dict.update = dict_mysql_update;
-    dict_mysql->dict.delete = dict_mysql_delete;
-    dict_mysql->dict.sequence = dict_mysql_sequence;
     dict_mysql->dict.close = dict_mysql_close;
-    dict_mysql->dict.fd = -1;                  /* there's no file descriptor
-                                                * for locking */
+    dict_mysql->dict.flags = dict_flags | DICT_FLAG_FIXED;
     dict_mysql->name = mysqlname_parse(name);
     dict_mysql->pldb = plmysql_init(dict_mysql->name->hostnames,
                                    dict_mysql->name->len_hosts);
     if (dict_mysql->pldb == NULL)
        msg_fatal("couldn't intialize pldb!\n");
     dict_register(name, (DICT *) dict_mysql);
-    return &dict_mysql->dict;
+    return (DICT_DEBUG(&dict_mysql->dict));
 }
 
 /* mysqlname_parse - parse mysql configuration file */
@@ -530,6 +527,7 @@ static void dict_mysql_close(DICT *dict)
     }
     myfree((char *) dict_mysql->name->hostnames);
     myfree((char *) dict_mysql->name);
+    dict_free(dict);
 }
 
 /* plmysql_dealloc - free memory associated with PLMYSQL close databases */
@@ -546,27 +544,4 @@ static void plmysql_dealloc(PLMYSQL *PLDB)
     myfree((char *) (PLDB));
 }
 
-
-/**********************************************************************
- * public interface dict_mysql_update - add or update table entry
- *
- *********************************************************************/
-static void dict_mysql_update(DICT *dict, const char *unused_name, const char *unused_value)
-{
-    DICT_MYSQL *dict_mysql = (DICT_MYSQL *) dict;
-
-    msg_fatal("dict_mysql_update: attempt to update mysql database");
-}
-
-static void dict_mysql_delete(DICT *unused_dict, const char *unused_name)
-{
-    msg_fatal("dict_mysql_delete: attempt to delete mysql database entry");
-}
-
-static void dict_mysql_sequence(DICT *unused_dict, const int unused_function,
-                        const char **unused_key, const char **unused_value)
-{
-    msg_fatal("dict_mysql_sequence: attempt to iterate over mysql database");
-}
-
 #endif
index fdb9395d32376dd5959fa4def432f761eec10c96..7fe559bd53cec2fad3d315f8a2f5ec226030068b 100644 (file)
@@ -1,14 +1,40 @@
-#ifdef HAS_MYSQL
+#ifndef _DICT_MYSQL_H_INCLUDED_
+#define _DICT_MYSQL_H_INCLUDED_
 
-#include <time.h>
-#include "mysql.h"
+/*++
+/* NAME
+/*     dict_mysql 3h
+/* SUMMARY
+/*     dictionary manager interface to mysql databases
+/* SYNOPSIS
+/*     #include <dict_mysql.h>
+/* DESCRIPTION
+/* .nf
 
-#define STATACTIVE 0
-#define STATFAIL 1
-#define STATUNTRIED 2
-#define RETRY_CONN_INTV 60             /* 1 minute */
+ /*
+  * Utility library.
+  */
+#include <dict.h>
 
-extern DICT *dict_mysql_open(const char *name, int unused_flags, int dict_flags);
+ /*
+  * External interface.
+  */
+#define DICT_TYPE_MYSQL        "mysql"
 
+extern DICT *dict_mysql_open(const char *, int, int);
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Scott Cotton
+/*     IC Group, Inc.
+/*     scott@icgroup.com
+/*
+/*     Joshua Marcus
+/*     IC Group, Inc.
+/*     josh@icgroup.com
+/*--*/
 
 #endif
index 6f1b6e0ea90b628aebc08aadff08fa619da39e1c..dafb687df5106efe58dc54323d558169877fd517 100644 (file)
@@ -151,45 +151,30 @@ static const char *dict_ni_lookup(DICT *dict, const char *key)
 {
     DICT_NI *d = (DICT_NI *) dict;
 
-    return dict_ni_do_lookup(d->path, NETINFO_PROP_KEY,
+    return dict_ni_do_lookup(d->dict.name, NETINFO_PROP_KEY,
                             key, NETINFO_PROP_VALUE);
 }
 
-/* dict_ni_update - add or update table entry (not!) */
-
-static void dict_ni_update(DICT *dict, const char *unused_name,
-                                  const char *unused_value)
-{
-    DICT_NI *d = (DICT_NI *) dict;
-
-    msg_fatal("dict_ni_update: unimplemented: update NetInfo directory %s",
-             d->path);
-}
-
 /* dict_ni_close - disassociate from NetInfo map */
 
 static void dict_ni_close(DICT *dict)
 {
     DICT_NI *d = (DICT_NI *) dict;
 
-    myfree(d->path);
-    myfree((char *) d);
+    dict_free(dict);
 }
 
 /* dict_ni_open - create association with NetInfo map */
 
 DICT   *dict_ni_open(const char *path, int unused_flags, int dict_flags)
 {
-    DICT_NI *d = (void *) mymalloc(sizeof(*d));
+    DICT_NI *d = (void *) dict_alloc(DICT_TYPE_NETINFO, path, sizeof(*d));
 
     d->dict.lookup = dict_ni_lookup;
-    d->dict.update = dict_ni_update;
     d->dict.close = dict_ni_close;
-    d->dict.fd = -1;
     d->dict.flags = dict_flags | DICT_FLAG_FIXED;
-    d->path = mystrdup(path);
 
-    return &d->dict;
+    return (DICT_DEBUG(&d->dict));
 }
 
 #endif
index b0221a4b6e2181854a37ca87882d276006a416ff..652b422f135a5d6b1aba23e6c5e2b64b32e2d8a0 100644 (file)
@@ -19,6 +19,8 @@
  /*
   * External interface.
   */
+#define DICT_TYPE_NETINFO      "netinfo"
+
 extern DICT *dict_ni_open(const char *, int, int);
 
 /* AUTHOR(S)
index 36bb99bb34b0caa785187922ea7ee0fc0c451274..f72c14aa289b7695657aacbc2fc77e3b25532a9a 100644 (file)
@@ -64,7 +64,6 @@
 
 typedef struct {
     DICT    dict;                      /* generic members */
-    char   *map;                       /* NIS map name */
 } DICT_NIS;
 
  /*
@@ -154,7 +153,7 @@ static const char *dict_nis_lookup(DICT *dict, const char *key)
      * value.
      */
     if (dict->flags & DICT_FLAG_TRY1NULL) {
-       err = yp_match(dict_nis_domain, dict_nis->map,
+       err = yp_match(dict_nis_domain, dict_nis->dict.name,
                       (void *) key, strlen(key) + 1,
                       &result, &result_len);
        if (err == 0) {
@@ -168,7 +167,7 @@ static const char *dict_nis_lookup(DICT *dict, const char *key)
      * value. This should never be the case, but better play safe.
      */
     if (dict->flags & DICT_FLAG_TRY0NULL) {
-       err = yp_match(dict_nis_domain, dict_nis->map,
+       err = yp_match(dict_nis_domain, dict_nis->dict.name,
                       (void *) key, strlen(key),
                       &result, &result_len);
        if (err == 0) {
@@ -187,30 +186,20 @@ static const char *dict_nis_lookup(DICT *dict, const char *key)
      */
     if (err != YPERR_KEY) {
        msg_warn("lookup %s, NIS domain %s, map %s: %s",
-                key, dict_nis_domain, dict_nis->map,
+                key, dict_nis_domain, dict_nis->dict.name,
                 dict_nis_strerror(err));
        dict_errno = DICT_ERR_RETRY;
     }
     return (0);
 }
 
-/* dict_nis_update - add or update table entry */
-
-static void dict_nis_update(DICT *dict, const char *unused_name, const char *unused_value)
-{
-    DICT_NIS *dict_nis = (DICT_NIS *) dict;
-
-    msg_fatal("dict_nis_update: attempt to update NIS map %s", dict_nis->map);
-}
-
 /* dict_nis_close - close NIS map */
 
 static void dict_nis_close(DICT *dict)
 {
     DICT_NIS *dict_nis = (DICT_NIS *) dict;
 
-    myfree(dict_nis->map);
-    myfree((char *) dict_nis);
+    dict_free(dict);
 }
 
 /* dict_nis_open - open NIS map */
@@ -219,18 +208,15 @@ DICT   *dict_nis_open(const char *map, int unused_flags, int dict_flags)
 {
     DICT_NIS *dict_nis;
 
-    dict_nis = (DICT_NIS *) mymalloc(sizeof(*dict_nis));
+    dict_nis = (DICT_NIS *) dict_alloc(DICT_TYPE_NIS, map, sizeof(*dict_nis));
     dict_nis->dict.lookup = dict_nis_lookup;
-    dict_nis->dict.update = dict_nis_update;
     dict_nis->dict.close = dict_nis_close;
-    dict_nis->dict.fd = -1;
-    dict_nis->map = mystrdup(map);
     dict_nis->dict.flags = dict_flags | DICT_FLAG_FIXED;
     if ((dict_flags & (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL)) == 0)
        dict_nis->dict.flags |= (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL);
     if (dict_nis_domain == 0)
        dict_nis_init();
-    return (&dict_nis->dict);
+    return (DICT_DEBUG(&dict_nis->dict));
 }
 
 #endif
index ff2759b7c5c1e98555bcad94ec8b4c8f80358e0f..97aa7cda94d5f9642cc7815b4d57eab4c9221997 100644 (file)
@@ -19,6 +19,8 @@
  /*
   * External interface.
   */
+#define DICT_TYPE_NIS  "nis"
+
 extern DICT *dict_nis_open(const char *, int, int);
 
 /* LICENSE
index 06c9d2fcd1b292736611694cb604000db50961fa..e6f3467d8afb83601164b2effad140708bca9790 100644 (file)
 
 typedef struct {
     DICT    dict;                      /* generic members */
-    char   *map;                       /* NISPLUS map name */
 } DICT_NISPLUS;
 
-/* dict_nisplus_lookup - find table entry */
-
-static const char *dict_nisplus_lookup(DICT *unused_dict, const char *unused_name)
-{
-    dict_errno = 0;
-    msg_warn("dict_nisplus_lookup: NISPLUS lookup not implemented");
-    return (0);
-}
-
-/* dict_nisplus_update - add or update table entry */
-
-static void dict_nisplus_update(DICT *dict, const char *unused_name, const char *unused_value)
-{
-    DICT_NISPLUS *dict_nisplus = (DICT_NISPLUS *) dict;
-
-    msg_fatal("dict_nisplus_update: attempt to update NIS+ map %s",
-             dict_nisplus->map);
-}
-
 /* dict_nisplus_close - close NISPLUS map */
 
 static void dict_nisplus_close(DICT *dict)
 {
     DICT_NISPLUS *dict_nisplus = (DICT_NISPLUS *) dict;
 
-    myfree(dict_nisplus->map);
     myfree((char *) dict_nisplus);
 }
 
@@ -82,12 +61,9 @@ DICT   *dict_nisplus_open(const char *map, int unused_flags, int dict_flags)
 {
     DICT_NISPLUS *dict_nisplus;
 
-    dict_nisplus = (DICT_NISPLUS *) mymalloc(sizeof(*dict_nisplus));
-    dict_nisplus->dict.lookup = dict_nisplus_lookup;
-    dict_nisplus->dict.update = dict_nisplus_update;
+    dict_nisplus = (DICT_NISPLUS *) dict_alloc(DICT_TYPE_NISPLUS, map,
+                                              sizeof(*dict_nisplus));
     dict_nisplus->dict.close = dict_nisplus_close;
-    dict_nisplus->dict.fd = -1;
-    dict_nisplus->map = mystrdup(map);
     dict_nisplus->dict.flags = dict_flags | DICT_FLAG_FIXED;
-    return (&dict_nisplus->dict);
+    return (DICT_DEBUG(&dict_nisplus->dict));
 }
index f43b3141ba932232ea0af3ef1bb97984f0490c44..1fd31c955047a786ce88d9252306213304981781 100644 (file)
@@ -19,6 +19,8 @@
  /*
   * External interface.
   */
+#define DICT_TYPE_NISPLUS      "nisplus"
+
 extern DICT *dict_nisplus_open(const char *, int, int);
 
 /* LICENSE
index e06c9daa156420668aa16b7507647634ded07c89..2c15ac897ef86d3d554f3ae75a4841fb42d36199 100644 (file)
@@ -179,38 +179,38 @@ typedef struct {
 } DICT_OPEN_INFO;
 
 static DICT_OPEN_INFO dict_open_info[] = {
-    "environ", dict_env_open,
-    "unix", dict_unix_open,
+    DICT_TYPE_ENVIRON, dict_env_open,
+    DICT_TYPE_UNIX, dict_unix_open,
 #if 0
-    "tcp", dict_tcp_open,
+    DICT_TYPE_TCP, dict_tcp_open,
 #endif
 #ifdef HAS_DBM
-    "dbm", dict_dbm_open,
+    DICT_TYPE_DBM, dict_dbm_open,
 #endif
 #ifdef HAS_DB
-    "hash", dict_hash_open,
-    "btree", dict_btree_open,
+    DICT_TYPE_HASH, dict_hash_open,
+    DICT_TYPE_BTREE, dict_btree_open,
 #endif
 #ifdef HAS_NIS
-    "nis", dict_nis_open,
+    DICT_TYPE_NIS, dict_nis_open,
 #endif
 #ifdef HAS_NISPLUS
-    "nisplus", dict_nisplus_open,
+    DICT_TYPE_NISPLUS, dict_nisplus_open,
 #endif
 #ifdef HAS_NETINFO
-    "netinfo", dict_ni_open,
+    DICT_TYPE_NETINFO, dict_ni_open,
 #endif
 #ifdef HAS_LDAP
-    "ldap", dict_ldap_open,
+    DICT_TYPE_LDAP, dict_ldap_open,
 #endif
 #ifdef HAS_MYSQL
-    "mysql", dict_mysql_open,
+    DICT_TYPE_MYSQL, dict_mysql_open,
 #endif
 #ifdef HAS_PCRE
-    "pcre", dict_pcre_open,
+    DICT_TYPE_PCRE, dict_pcre_open,
 #endif
 #ifdef HAS_POSIX_REGEXP
-    "regexp", dict_regexp_open,
+    DICT_TYPE_REGEXP, dict_regexp_open,
 #endif
     0,
 };
index 019f3f449876da461b53180b4aee29457c036f29..1e8e84b6bf5a33ff28fd5bcafd25e38172bcd74c 100644 (file)
@@ -70,25 +70,11 @@ struct dict_pcre_list {
 
 typedef struct {
     DICT    dict;                      /* generic members */
-    char   *map;                       /* map name */
-    int     flags;                     /* unused at the moment */
     struct dict_pcre_list *head;
 } DICT_PCRE;
 
 static  dict_pcre_init = 0;            /* flag need to init pcre library */
 
-/*
- *  dict_pcre_update - not supported
- */
-static void dict_pcre_update(DICT *dict, const char *unused_name,
-                                    const char *unused_value)
-{
-    DICT_PCRE *dict_pcre = (DICT_PCRE *) dict;
-
-    msg_fatal("dict_pcre_update: attempt to update regexp map %s",
-             dict_pcre->map);
-}
-
 /*
  * Context for macro expansion callback.
  */
@@ -153,7 +139,7 @@ static const char *dict_pcre_lookup(DICT *dict, const char *name)
     dict_errno = 0;
 
     if (msg_verbose)
-       msg_info("dict_pcre_lookup: %s: %s", dict_pcre->map, name);
+       msg_info("dict_pcre_lookup: %s: %s", dict_pcre->dict.name, name);
 
     /* Search for a matching expression */
     ctxt.matches = 0;
@@ -168,22 +154,22 @@ static const char *dict_pcre_lookup(DICT *dict, const char *name)
                    /* An error */
                    switch (ctxt.matches) {
                    case 0:
-                       msg_warn("regexp map %s, line %d: too many (...)",
-                                dict_pcre->map, pcre_list->lineno);
+                       msg_warn("pcre map %s, line %d: too many (...)",
+                                dict_pcre->dict.name, pcre_list->lineno);
                        break;
                    case PCRE_ERROR_NULL:
                    case PCRE_ERROR_BADOPTION:
-                       msg_fatal("regexp map %s, line %d: bad args to re_exec",
-                                 dict_pcre->map, pcre_list->lineno);
+                       msg_fatal("pcre map %s, line %d: bad args to re_exec",
+                                 dict_pcre->dict.name, pcre_list->lineno);
                        break;
                    case PCRE_ERROR_BADMAGIC:
                    case PCRE_ERROR_UNKNOWN_NODE:
-                       msg_fatal("regexp map %s, line %d: corrupt compiled regexp",
-                                 dict_pcre->map, pcre_list->lineno);
+                       msg_fatal("pcre map %s, line %d: corrupt compiled regexp",
+                                 dict_pcre->dict.name, pcre_list->lineno);
                        break;
                    default:
-                       msg_fatal("regexp map %s, line %d: unknown re_exec error: %d",
-                          dict_pcre->map, pcre_list->lineno, ctxt.matches);
+                       msg_fatal("pcre map %s, line %d: unknown re_exec error: %d",
+                                 dict_pcre->dict.name, pcre_list->lineno, ctxt.matches);
                        break;
                    }
                    return ((char *) 0);
@@ -200,12 +186,12 @@ static const char *dict_pcre_lookup(DICT *dict, const char *name)
        VSTRING_RESET(buf);
        ctxt.buf = buf;
        ctxt.subject = name;
-       ctxt.dict_name = dict_pcre->map;
+       ctxt.dict_name = dict_pcre->dict.name;
        ctxt.lineno = pcre_list->lineno;
 
        if (mac_parse(pcre_list->replace, dict_pcre_action, (char *) &ctxt) & MAC_PARSE_ERROR)
-           msg_fatal("regexp map %s, line %d: bad replacement syntax",
-                     dict_pcre->map, pcre_list->lineno);
+           msg_fatal("pcre map %s, line %d: bad replacement syntax",
+                     dict_pcre->dict.name, pcre_list->lineno);
 
        VSTRING_TERMINATE(buf);
        return (vstring_str(buf));
@@ -219,17 +205,19 @@ static void dict_pcre_close(DICT *dict)
 {
     DICT_PCRE *dict_pcre = (DICT_PCRE *) dict;
     struct dict_pcre_list *pcre_list;
+    struct dict_pcre_list *next;
 
-    for (pcre_list = dict_pcre->head; pcre_list; pcre_list = pcre_list->next) {
+    for (pcre_list = dict_pcre->head; pcre_list; pcre_list = next) {
+       next = pcre_list->next;
        if (pcre_list->pattern)
            myfree((char *) pcre_list->pattern);
        if (pcre_list->hints)
            myfree((char *) pcre_list->hints);
        if (pcre_list->replace)
            myfree((char *) pcre_list->replace);
+       myfree((char *) pcre_list);
     }
-    myfree(dict_pcre->map);
-    myfree((char *) dict_pcre);
+    dict_free(dict);
 }
 
 /*
@@ -254,12 +242,10 @@ DICT   *dict_pcre_open(const char *map, int unused_flags, int dict_flags)
 
     line_buffer = vstring_alloc(100);
 
-    dict_pcre = (DICT_PCRE *) mymalloc(sizeof(*dict_pcre));
+    dict_pcre = (DICT_PCRE *) dict_alloc(DICT_TYPE_PCRE, map,
+                                        sizeof(*dict_pcre));
     dict_pcre->dict.lookup = dict_pcre_lookup;
-    dict_pcre->dict.update = dict_pcre_update;
     dict_pcre->dict.close = dict_pcre_close;
-    dict_pcre->dict.fd = -1;
-    dict_pcre->map = mystrdup(map);
     dict_pcre->dict.flags = dict_flags | DICT_FLAG_PATTERN;
     dict_pcre->head = NULL;
 
@@ -378,7 +364,7 @@ DICT   *dict_pcre_open(const char *map, int unused_flags, int dict_flags)
     vstring_free(line_buffer);
     vstream_fclose(map_fp);
 
-    return (&dict_pcre->dict);
+    return (DICT_DEBUG(&dict_pcre->dict));
 }
 
 #endif                                 /* HAS_PCRE */
index 253c69e78f57acdfe0ee74d355b52aa4ff427eef..3aa49559b2cae2c5bbc4a0dc972bea24835dd3ce 100644 (file)
@@ -19,6 +19,8 @@
  /*
   * External interface.
   */
+#define DICT_TYPE_PCRE "pcre"
+
 extern DICT *dict_pcre_open(const char *, int, int);
 
 /* LICENSE
index 7f86f083dba34c7f363ce495ea180ab670e2b8ff..0d4eaf852352693c00d706117c6050e3cbc5f5ef 100644 (file)
@@ -82,18 +82,6 @@ struct dict_regexp_context {
     const char *subject;               /* str against which we match */
 };
 
-/*
- *  dict_regexp_update - not supported
- */
-static void dict_regexp_update(DICT *dict, const char *unused_name,
-                                      const char *unused_value)
-{
-    DICT_REGEXP *dict_regexp = (DICT_REGEXP *) dict;
-
-    msg_fatal("dict_regexp_update: attempt to update regexp map %s",
-             dict_regexp->map);
-}
-
 /*
  * Macro expansion callback - replace $0-${99} with strings cut from
  * matched string.
@@ -109,7 +97,7 @@ static int dict_regexp_action(int type, VSTRING *buf, char *ptr)
        n = atoi(vstring_str(buf));
        if (n >= dict->nmatch)
            msg_fatal("regexp %s, line %d: replacement index out of range",
-                     dict->map, rule->lineno);
+                     dict->dict.name, rule->lineno);
        if (dict->pmatch[n].rm_so < 0 ||
            dict->pmatch[n].rm_so == dict->pmatch[n].rm_eo) {
            return (MAC_PARSE_UNDEF);           /* empty string or not
@@ -138,7 +126,7 @@ static const char *dict_regexp_lookup(DICT *dict, const char *name)
     dict_errno = 0;
 
     if (msg_verbose)
-       msg_info("dict_regexp_lookup: %s: %s", dict_regexp->map, name);
+       msg_info("dict_regexp_lookup: %s: %s", dict_regexp->dict.name, name);
 
     /* Search for a matching expression */
     for (rule = dict_regexp->head; rule; rule = rule->next) {
@@ -155,7 +143,7 @@ static const char *dict_regexp_lookup(DICT *dict, const char *name)
 
                    (void) regerror(error, rule->expr[1], errbuf, sizeof(errbuf));
                    msg_fatal("regexp map %s, line %d: %s.",
-                             dict_regexp->map, rule->lineno, errbuf);
+                             dict_regexp->dict.name, rule->lineno, errbuf);
                }
            }
 
@@ -174,7 +162,7 @@ static const char *dict_regexp_lookup(DICT *dict, const char *name)
 
            if (mac_parse(rule->replace, dict_regexp_action, (char *) &ctxt) & MAC_PARSE_ERROR)
                msg_fatal("regexp map %s, line %d: bad replacement syntax.",
-                         dict_regexp->map, rule->lineno);
+                         dict_regexp->dict.name, rule->lineno);
 
            VSTRING_TERMINATE(buf);
            return (vstring_str(buf));
@@ -183,7 +171,7 @@ static const char *dict_regexp_lookup(DICT *dict, const char *name)
 
            (void) regerror(error, rule->expr[0], errbuf, sizeof(errbuf));
            msg_fatal("regexp map %s, line %d: %s.",
-                     dict_regexp->map, rule->lineno, errbuf);
+                     dict_regexp->dict.name, rule->lineno, errbuf);
            return ((char *) 0);
        }
     }
@@ -212,8 +200,7 @@ static void dict_regexp_close(DICT *dict)
     }
     if (dict_regexp->pmatch)
        myfree((char *) dict_regexp->pmatch);
-    myfree(dict_regexp->map);
-    myfree((char *) dict_regexp);
+    dict_free(dict);
 }
 
 static regex_t *dict_regexp_get_expr(int lineno, char **bufp, VSTREAM *map_fp)
@@ -358,12 +345,10 @@ DICT   *dict_regexp_open(const char *map, int unused_flags, int dict_flags)
 
     line_buffer = vstring_alloc(100);
 
-    dict_regexp = (DICT_REGEXP *) mymalloc(sizeof(*dict_regexp));
+    dict_regexp = (DICT_REGEXP *) dict_alloc(DICT_TYPE_REGEXP, map,
+                                            sizeof(*dict_regexp));
     dict_regexp->dict.lookup = dict_regexp_lookup;
-    dict_regexp->dict.update = dict_regexp_update;
     dict_regexp->dict.close = dict_regexp_close;
-    dict_regexp->dict.fd = -1;
-    dict_regexp->map = mystrdup(map);
     dict_regexp->dict.flags = dict_flags | DICT_FLAG_PATTERN;
     dict_regexp->head = 0;
     dict_regexp->pmatch = 0;
@@ -401,7 +386,7 @@ DICT   *dict_regexp_open(const char *map, int unused_flags, int dict_flags)
     vstring_free(line_buffer);
     vstream_fclose(map_fp);
 
-    return (&dict_regexp->dict);
+    return (DICT_DEBUG(&dict_regexp->dict));
 }
 
 #endif
index f487bedf6b2050a4a3fbd61377a194240f6f68e5..2874b2708093b21954880ae0573955f98cecc7e3 100644 (file)
@@ -19,6 +19,8 @@
  /*
   * External interface.
   */
+#define DICT_TYPE_REGEXP       "regexp"
+
 extern DICT *dict_regexp_open(const char *, int, int);
 
 /* AUTHOR(S)
index ccb516292338b609a51813de6af88aaa53ed92d5..6686055802e5dc4dadfa95eb08cf2c1f5903671d 100644 (file)
@@ -98,7 +98,6 @@
 
 typedef struct {
     DICT    dict;                      /* generic members */
-    char   *map;                       /* server host:port */
     VSTRING *raw_buf;                  /* raw I/O buffer */
     VSTRING *hex_buf;                  /* quoted I/O buffer */
     VSTREAM *fp;                       /* I/O stream */
@@ -119,8 +118,8 @@ static int dict_tcp_connect(DICT_TCP *dict_tcp)
      * Connect to the server. Enforce a time limit on read/write operations
      * so that we do not get stuck.
      */
-    if ((fd = inet_connect(dict_tcp->map, BLOCKING, 0)) < 0) {
-       msg_warn("connect to TCP map %s: %m", dict_tcp->map);
+    if ((fd = inet_connect(dict_tcp->dict.name, BLOCKING, 0)) < 0) {
+       msg_warn("connect to TCP map %s: %m", dict_tcp->dict.name);
        return (-1);
     }
     dict_tcp->fp = vstream_fdopen(fd, O_RDWR);
@@ -181,7 +180,7 @@ static const char *dict_tcp_lookup(DICT *dict, const char *key)
             * Disconnect from the server if it can't talk to us.
             */
            msg_warn("read TCP map reply from %s: unexpected EOF (%m)",
-                    dict_tcp->map);
+                    dict_tcp->dict.name);
            dict_tcp_disconnect(dict_tcp);
        }
 
@@ -206,7 +205,7 @@ static const char *dict_tcp_lookup(DICT *dict, const char *key)
        || !ISDIGIT(start[2]) || !ISSPACE(start[3])
        || !hex_unquote(dict_tcp->raw_buf, start + 4)) {
        msg_warn("read TCP map reply from %s: malformed reply %.100s",
-                dict_tcp->map, printable(STR(dict_tcp->hex_buf), '_'));
+                dict_tcp->dict.name, printable(STR(dict_tcp->hex_buf), '_'));
        dict_tcp_disconnect(dict_tcp);
        RETURN(DICT_ERR_RETRY, 0);
     }
@@ -218,7 +217,7 @@ static const char *dict_tcp_lookup(DICT *dict, const char *key)
     switch (start[0]) {
     default:
        msg_warn("read TCP map reply from %s: bad status code %.100s",
-                dict_tcp->map, printable(STR(dict_tcp->hex_buf), '_'));
+                dict_tcp->dict.name, printable(STR(dict_tcp->hex_buf), '_'));
        dict_tcp_disconnect(dict_tcp);
        RETURN(DICT_ERR_RETRY, 0);
     case '4':
@@ -240,34 +239,6 @@ static const char *dict_tcp_lookup(DICT *dict, const char *key)
     }
 }
 
-/* dict_tcp_update - add or update table entry */
-
-static void dict_tcp_update(DICT *dict, const char *unused_name, const char *unused_value)
-{
-    DICT_TCP *dict_tcp = (DICT_TCP *) dict;
-
-    msg_fatal("dict_tcp_update: attempt to update map %s", dict_tcp->map);
-}
-
-/* dict_tcp_delete - remove table entry */
-
-static int dict_tcp_delete(DICT *dict, const char *unused_name)
-{
-    DICT_TCP *dict_tcp = (DICT_TCP *) dict;
-
-    msg_fatal("dict_tcp_delete: attempt to update map %s", dict_tcp->map);
-}
-
-/* dict_tcp_sequence - iterate over table */
-
-static int dict_tcp_sequence(DICT *dict, int unused_func,
-                       const char **unused_name, const char **unused_value)
-{
-    DICT_TCP *dict_tcp = (DICT_TCP *) dict;
-
-    msg_fatal("dict_tcp_sequence: attempt to iterate map %s", dict_tcp->map);
-}
-
 /* dict_tcp_close - close TCP map */
 
 static void dict_tcp_close(DICT *dict)
@@ -280,8 +251,7 @@ static void dict_tcp_close(DICT *dict)
        vstring_free(dict_tcp->raw_buf);
     if (dict_tcp->hex_buf)
        vstring_free(dict_tcp->hex_buf);
-    myfree(dict_tcp->map);
-    myfree((char *) dict_tcp);
+    dict_free(dict);
 }
 
 /* dict_tcp_open - open TCP map */
@@ -292,16 +262,11 @@ DICT   *dict_tcp_open(const char *map, int unused_flags, int dict_flags)
 
     dict_errno = 0;
 
-    dict_tcp = (DICT_TCP *) mymalloc(sizeof(*dict_tcp));
+    dict_tcp = (DICT_TCP *) dict_alloc(DICT_TYPE_TCP, map, sizeof(*dict_tcp));
     dict_tcp->fp = 0;
     dict_tcp->raw_buf = dict_tcp->hex_buf = 0;
     dict_tcp->dict.lookup = dict_tcp_lookup;
-    dict_tcp->dict.update = dict_tcp_update;
-    dict_tcp->dict.delete = dict_tcp_delete;
-    dict_tcp->dict.sequence = dict_tcp_sequence;
     dict_tcp->dict.close = dict_tcp_close;
-    dict_tcp->dict.fd = -1;
-    dict_tcp->map = mystrdup(map);
     dict_tcp->dict.flags = dict_flags | DICT_FLAG_FIXED;
-    return (&dict_tcp->dict);
+    return (DICT_DEBUG(&dict_tcp->dict));
 }
index 4b31edad6676ecebe4164287fa0b8e4ac3f85248..9814c61ff82ae303cad8155a204a5f86ff624d82 100644 (file)
@@ -19,6 +19,8 @@
  /*
   * External interface.
   */
+#define DICT_TYPE_TCP  "tcp"
+
 extern DICT *dict_tcp_open(const char *, int, int);
 
 /* LICENSE
index 0b261de199df8abf62d923cffd97f133e68ea61c..1409746c6d9a7a8ce1ca2c451dd99889e321e798 100644 (file)
@@ -57,7 +57,6 @@
 
 typedef struct {
     DICT    dict;                      /* generic members */
-    char   *map;                       /* UNIX map name */
 } DICT_UNIX;
 
 /* dict_unix_getpwnam - find password table entry */
@@ -109,23 +108,13 @@ static const char *dict_unix_getgrnam(DICT *unused_dict, const char *key)
     }
 }
 
-/* dict_unix_update - add or update table entry */
-
-static void dict_unix_update(DICT *dict, const char *unused_name, const char *unused_value)
-{
-    DICT_UNIX *dict_unix = (DICT_UNIX *) dict;
-
-    msg_fatal("dict_unix_update: attempt to update map %s", dict_unix->map);
-}
-
 /* dict_unix_close - close UNIX map */
 
 static void dict_unix_close(DICT *dict)
 {
     DICT_UNIX *dict_unix = (DICT_UNIX *) dict;
 
-    myfree(dict_unix->map);
-    myfree((char *) dict_unix);
+    dict_free(dict);
 }
 
 /* dict_unix_open - open UNIX map */
@@ -146,7 +135,8 @@ DICT   *dict_unix_open(const char *map, int unused_flags, int dict_flags)
 
     dict_errno = 0;
 
-    dict_unix = (DICT_UNIX *) mymalloc(sizeof(*dict_unix));
+    dict_unix = (DICT_UNIX *) dict_alloc(DICT_TYPE_UNIX, map,
+                                        sizeof(*dict_unix));
     for (lp = dict_unix_lookup; /* void */ ; lp++) {
        if (lp->name == 0)
            msg_fatal("dict_unix_open: unknown map name: %s", map);
@@ -154,10 +144,7 @@ DICT   *dict_unix_open(const char *map, int unused_flags, int dict_flags)
            break;
     }
     dict_unix->dict.lookup = lp->lookup;
-    dict_unix->dict.update = dict_unix_update;
     dict_unix->dict.close = dict_unix_close;
-    dict_unix->dict.fd = -1;
-    dict_unix->map = mystrdup(map);
     dict_unix->dict.flags = dict_flags | DICT_FLAG_FIXED;
-    return (&dict_unix->dict);
+    return (DICT_DEBUG(&dict_unix->dict));
 }
index b82a1ec8fee722ec58e206c67e344f7dfcca4340..b5674b29236bda6ea8627fd526b17c7af0a5adc0 100644 (file)
@@ -19,6 +19,8 @@
  /*
   * External interface.
   */
+#define DICT_TYPE_UNIX "unix"
+
 extern DICT *dict_unix_open(const char *, int, int);
 
 /* LICENSE
index 38017ed9ee4a35ee8088d83bf3b9b43f163957d2..04f23f6e542e612a1812e4248239da50c73ca27d 100644 (file)
@@ -34,6 +34,7 @@
 /* Utility library. */
 
 #include "iostuff.h"
+#include "sane_socketpair.h"
 
 /* duplex_pipe - give me a duplex pipe or bust */
 
@@ -42,7 +43,7 @@ int     duplex_pipe(int *fds)
 #ifdef HAS_DUPLEX_PIPE
     return (pipe(fds));
 #else
-    return (socketpair(AF_UNIX, SOCK_STREAM, 0, fds));
+    return (sane_socketpair(AF_UNIX, SOCK_STREAM, 0, fds));
 #endif
 }
 
index dacb818fe99b54b51978aab7c709d2495864a93d..fcf4a7f7ffb760e01406453dd2f95cb1880b0299 100644 (file)
@@ -66,7 +66,7 @@ const char *get_hostname(void)
        if (gethostname(namebuf, sizeof(namebuf)) < 0)
            msg_fatal("gethostname: %m");
        namebuf[MAXHOSTNAMELEN] = 0;
-       if (valid_hostname(namebuf) == 0)
+       if (valid_hostname(namebuf, DO_GRIPE) == 0)
            msg_fatal("unable to use my own hostname");
        my_host_name = mystrdup(namebuf);
     }
index 9a53d8d6f8a40b4e94965b24585916094929cbc3..0a3cb22a8a8960289c2ba0ed7d70269b306acb39 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 a list that
+/*     receives the netmasks of the interface addresses that were found.
 /* DIAGNOSTICS
 /*     Fatal errors: out of memory.
 /* SEE ALSO
@@ -42,6 +46,7 @@
 #include <sys/sockio.h>
 #endif
 #include <errno.h>
+#include <string.h>
 
 /* Utility library. */
 
 #ifdef _SIZEOF_ADDR_IFREQ
 #define NEXT_INTERFACE(ifr) ((struct ifreq *) \
        ((char *) ifr + _SIZEOF_ADDR_IFREQ(*ifr)))
+#define IFREQ_SIZE(ifr)        _SIZEOF_ADDR_IFREQ(*ifr)
 #else
 #ifdef HAS_SA_LEN
 #define NEXT_INTERFACE(ifr) ((struct ifreq *) \
        ((char *) ifr + sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len))
+#define IFREQ_SIZE(ifr)        (sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len)
 #else
 #define NEXT_INTERFACE(ifr) (ifr + 1)
+#define IFREQ_SIZE(ifr)        sizeof(ifr[0])
 #endif
 #endif
 
 /* 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;
@@ -78,6 +86,7 @@ int     inet_addr_local(INET_ADDR_LIST *addr_list)
     VSTRING *buf = vstring_alloc(1024);
     int     initial_count = addr_list->used;
     struct in_addr addr;
+    struct ifreq *ifr_mask;
 
     if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
        msg_fatal("%s: socket: %m", myname);
@@ -119,8 +128,18 @@ 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) {
+                   ifr_mask = (struct ifreq *) mymalloc(IFREQ_SIZE(ifr));
+                   memcpy((char *) ifr_mask, (char *) ifr, IFREQ_SIZE(ifr));
+                   if (ioctl(sock, SIOCGIFNETMASK, ifr_mask) < 0)
+                       msg_fatal("%s: ioctl SIOCGIFNETMASK: %m", myname);
+                   addr = ((struct sockaddr_in *) & ifr_mask->ifr_addr)->sin_addr;
+                   inet_addr_list_append(mask_list, &addr);
+                   myfree((char *) ifr_mask);
+               }
+           }
        }
        ifr = NEXT_INTERFACE(ifr);
     }
@@ -137,12 +156,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 +171,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 851c091c8a86fc2fcc3672560aa2ef514ff91e33..7da0f297db022e0f913aff5deeaa75ad43fe8e52 100644 (file)
@@ -27,6 +27,7 @@ extern int write_buf(int, const char *, int, int);
 extern int timed_read(int, void *, unsigned, int, void *);
 extern int timed_write(int, void *, unsigned, int, void *);
 extern void doze(unsigned);
+extern void rand_sleep(unsigned, unsigned);
 extern int duplex_pipe(int *);
 
 #define BLOCKING       0
diff --git a/postfix/src/util/rand_sleep.c b/postfix/src/util/rand_sleep.c
new file mode 100644 (file)
index 0000000..0173e96
--- /dev/null
@@ -0,0 +1,95 @@
+/*++
+/* NAME
+/*     rand_sleep 3
+/* SUMMARY
+/*     sleep for randomized interval
+/* SYNOPSIS
+/*     #include <iostuff.h>
+/*
+/*     void    rand_sleep(delay, variation)
+/*     unsigned delay;
+/*     unsigned variation;
+/* DESCRIPTION
+/*     rand_sleep() blocks the current process for an amount of time
+/*     pseudo-randomly chosen from the interval (delay +- variation/2).
+/*
+/*     Arguments:
+/* .IP delay
+/*     Time to sleep in microseconds.
+/* .IP variation
+/*     Variation in microseconds; must not be larger than delay.
+/* DIAGNOSTICS
+/*     Panic: interface violation. All system call errors are fatal.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+
+#ifndef RAND_MAX
+#define RAND_MAX 0x7fffffff
+#endif
+
+/* Utility library. */
+
+#include <msg.h>
+#include <iostuff.h>
+
+/* rand_sleep - block for random time */
+
+void    rand_sleep(unsigned delay, unsigned variation)
+{
+    char   *myname = "rand_sleep";
+    static pid_t my_pid;
+    unsigned usec;
+
+    /*
+     * Sanity checks.
+     */
+    if (delay == 0)
+       msg_panic("%s: bad delay %d", myname, delay);
+    if (variation > delay)
+       msg_panic("%s: bad variation %d", myname, variation);
+
+    /*
+     * Use the semi-crappy random number generator.
+     */
+    if (my_pid == 0)
+       srandom((my_pid = getpid()) ^ time((time_t *) 0));
+    usec = (delay - variation / 2) + variation * (double) random() / RAND_MAX;
+    doze(usec);
+}
+
+#ifdef TEST
+
+#include <msg_vstream.h>
+
+int     main(int argc, char **argv)
+{
+    int     delay;
+    int     variation;
+
+    msg_vstream_init(argv[0], VSTREAM_ERR);
+    if (argc != 3)
+       msg_fatal("usage: %s delay variation", argv[0]);
+    if ((delay = atoi(argv[1])) <= 0)
+       msg_fatal("bad delay: %s", argv[1]);
+    if ((variation = atoi(argv[2])) < 0)
+       msg_fatal("bad variation: %s", argv[2]);
+    rand_sleep(delay * 1000000, variation * 1000000);
+    exit(0);
+}
+
+#endif
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;
 
diff --git a/postfix/src/util/sane_socketpair.c b/postfix/src/util/sane_socketpair.c
new file mode 100644 (file)
index 0000000..c1d3568
--- /dev/null
@@ -0,0 +1,71 @@
+/*++
+/* NAME
+/*     sane_socketpair 3
+/* SUMMARY
+/*     sanitize socketpair() error returns
+/* SYNOPSIS
+/*     #include <sane_socketpair.h>
+/*
+/*     int     sane_socketpair(domain, type, protocol, result)
+/*     int     domain;
+/*     int     type;
+/*     int     protocol;
+/*     int     *result;
+/* DESCRIPTION
+/*     sane_socketpair() implements the socketpair(2) socket call, and
+/*     skips over silly error results such as EINTR.
+/* BUGS
+/*     Bizarre systems may have other harmless error results. Such
+/*     systems encourage programers to ignore error results, and
+/*     penalizes programmers who code defensively.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include "sys_defs.h"
+#include <sys/socket.h>
+#include <unistd.h>
+#include <errno.h>
+
+/* Utility library. */
+
+#include "msg.h"
+#include "sane_socketpair.h"
+
+/* sane_socketpair - sanitize socketpair() error returns */
+
+int     sane_socketpair(int domain, int type, int protocol, int *result)
+{
+    static int socketpair_ok_errors[] = {
+       EINTR,
+       0,
+    };
+    int     count;
+    int     err;
+    int     ret;
+
+    /*
+     * Solaris socketpair() can fail with EINTR.
+     */
+    while ((ret = socketpair(domain, type, protocol, result)) < 0) {
+       for (count = 0; /* void */ ; count++) {
+           if ((err = socketpair_ok_errors[count]) == 0)
+               return (ret);
+           if (errno == err) {
+               msg_warn("socketpair: %m (trying again)");
+               sleep(1);
+               break;
+           }
+       }
+    }
+    return (ret);
+}
diff --git a/postfix/src/util/sane_socketpair.h b/postfix/src/util/sane_socketpair.h
new file mode 100644 (file)
index 0000000..3c8e239
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _SANE_SOCKETPAIR_H_
+#define _SANE_SOCKETPAIR_H_
+
+/*++
+/* NAME
+/*     sane_socketpair 3h
+/* SUMMARY
+/*     sanitize socketpair() error returns
+/* SYNOPSIS
+/*     #include <sane_socketpair.h>
+/* DESCRIPTION
+/* .nf
+
+ /* External interface. */
+
+extern int sane_socketpair(int, int, int, int *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif
diff --git a/postfix/src/util/sane_time.c b/postfix/src/util/sane_time.c
new file mode 100644 (file)
index 0000000..157c95e
--- /dev/null
@@ -0,0 +1,128 @@
+/*++
+/* NAME
+/*     sane_time 3
+/* SUMMARY
+/*     time(2) with backward time jump protection.
+/* SYNOPSIS
+/*     #include <sane_time.h>
+/*
+/*     time_t sane_time(void)
+/*
+/* DESCRIPTION
+/*     This module provides time(2) like call for applications
+/*     which need monotonically increasing time function rather
+/*     than the real exact time. It eliminates the need for various
+/*     workarounds all over the application which would handle
+/*     potential problems if time suddenly jumps backward.
+/*     Instead we choose to deal with this problem inside this
+/*     module and let the application focus on its own tasks.
+/*
+/*     sane_time() returns the current timestamp as obtained from
+/*     time(2) call, at least most of the time. In case this routine
+/*     detects that time has jumped backward, it keeps returning
+/*     whatever timestamp it returned before, until this timestamp
+/*     and the time(2) timestamp become synchronized again.
+/*     Additionally, the returned timestamp is slowly increased to
+/*     prevent the faked clock from freezing for too long.
+/* SEE ALSO
+/*     time(2) get current time
+/* DIAGNOSTICS
+/*     Warning message is logged if backward time jump is detected.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Patrik Rak
+/*     Modra 6
+/*     155 00, Prague, Czech Republic
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+#include <msg.h>
+
+/* Application-specific. */
+
+#include "sane_time.h"
+
+/*
+ * How many times shall we slow down the real clock when recovering from
+ * time jump.
+ */
+#define SLEW_FACTOR 2
+
+/* sane_time - get current time, protected against time warping */
+
+time_t  sane_time(void)
+{
+    time_t  now;
+    static time_t last_time,
+            last_real;
+    int     delta;
+    static int fraction;
+    static int warned;
+
+    now = time((time_t *) 0);
+
+    if ((delta = now - last_time) < 0 && last_time != 0) {
+       if ((delta = now - last_real) < 0) {
+           msg_warn("%sbackward time jump detected -- slewing clock",
+                    warned++ ? "another " : "");
+       } else {
+           delta += fraction;
+           last_time += delta / SLEW_FACTOR;
+           fraction = delta % SLEW_FACTOR;
+       }
+    } else {
+       if (warned) {
+           warned = 0;
+           msg_warn("backward time jump recovered -- back to normality");
+           fraction = 0;
+       }
+       last_time = now;
+    }
+    last_real = now;
+
+    return (last_time);
+}
+
+#ifdef TEST
+
+ /*
+  * Proof-of-concept test program. Repeatedly print current system time and
+  * time returned by sane_time(). Meanwhile, try stepping your system clock
+  * back and forth to see what happens.
+  */
+
+#include <stdlib.h>
+#include <msg_vstream.h>
+#include <iostuff.h>                   /* doze() */
+
+int     main(int argc, char **argv)
+{
+    int     delay = 1000000;
+    time_t  now;
+
+    msg_vstream_init(argv[0], VSTREAM_ERR);
+
+    if (argc == 2 && (delay = atol(argv[1]) * 1000) > 0)
+        /* void */ ;
+    else if (argc != 1)
+       msg_fatal("usage: %s [delay in ms (default 1 second)]", argv[0]);
+
+    for (;;) {
+       now = time((time_t *) 0);
+       vstream_printf("real: %s", ctime(&now));
+       now = sane_time();
+       vstream_printf("fake: %s\n", ctime(&now));
+       vstream_fflush(VSTREAM_OUT);
+       doze(delay);
+    }
+}
+
+#endif
diff --git a/postfix/src/util/sane_time.h b/postfix/src/util/sane_time.h
new file mode 100644 (file)
index 0000000..0fe50d9
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef _SANE_TIME_H_
+#define _SANE_TIME_H_
+
+/*++
+/* NAME
+/*     sane_time 3h
+/* SUMMARY
+/*     time(2) with backward time jump protection
+/* SYNOPSIS
+/*     #include <sane_time.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * System library.
+  */
+#include <time.h>
+
+ /*
+  * External interface.
+  */
+extern time_t sane_time(void);
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Patrik Rak
+/*     Modra 6
+/*     155 00, Prague, Czech Republic
+/*--*/
+
+#endif
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
index 29f305fd821eab5f9e8eeb1fbce70547ef7f47c0..fa628c4881c28d4c14929e450bdd5f21c1f13b29 100644 (file)
@@ -6,11 +6,13 @@
 /* SYNOPSIS
 /*     #include <valid_hostname.h>
 /*
-/*     int     valid_hostname(name)
+/*     int     valid_hostname(name, gripe)
 /*     const char *name;
+/*     int     gripe;
 /*
-/*     int     valid_hostaddr(addr)
+/*     int     valid_hostaddr(addr, gripe)
 /*     const char *addr;
+/*     int     gripe;
 /* DESCRIPTION
 /*     valid_hostname() scrutinizes a hostname: the name should be no
 /*     longer than VALID_HOSTNAME_LEN characters, should contain only
 /*
 /*     valid_hostaddr() requirs that the input is a valid string
 /*     representation of an internet network address.
+/*
+/*     These routines operate silently unless the gripe parameter
+/*     specifies a non-zero value. The macros DO_GRIPE and DONT_GRIPE
+/*     provide suitable constants.
 /* DIAGNOSTICS
 /*     Both functions return zero if they disagree with the input.
 /* SEE ALSO
@@ -50,7 +56,7 @@
 
 /* valid_hostname - screen out bad hostnames */
 
-int     valid_hostname(const char *name)
+int     valid_hostname(const char *name, int gripe)
 {
     char   *myname = "valid_hostname";
     const char *cp;
@@ -63,7 +69,8 @@ int     valid_hostname(const char *name)
      * Trivial cases first.
      */
     if (*name == 0) {
-       msg_warn("%s: empty hostname", myname);
+       if (gripe)
+           msg_warn("%s: empty hostname", myname);
        return (0);
     }
 
@@ -76,37 +83,43 @@ int     valid_hostname(const char *name)
                label_count++;
            label_length++;
            if (label_length > VALID_LABEL_LEN) {
-               msg_warn("%s: hostname label too long: %.100s", myname, name);
+               if (gripe)
+                   msg_warn("%s: hostname label too long: %.100s", myname, name);
                return (0);
            }
            if (!ISDIGIT(ch))
                non_numeric = 1;
        } else if (ch == '.') {
            if (label_length == 0 || cp[1] == 0) {
-               msg_warn("%s: misplaced delimiter: %.100s", myname, name);
+               if (gripe)
+                   msg_warn("%s: misplaced delimiter: %.100s", myname, name);
                return (0);
            }
            label_length = 0;
        } else if (ch == '-') {
            label_length++;
            if (label_length == 1 || cp[1] == 0 || cp[1] == '.') {
-               msg_warn("%s: misplaced hyphen: %.100s", myname, name);
+               if (gripe)
+                   msg_warn("%s: misplaced hyphen: %.100s", myname, name);
                return (0);
            }
        } else {
-           msg_warn("%s: invalid character %d(decimal): %.100s",
-                    myname, ch, name);
+           if (gripe)
+               msg_warn("%s: invalid character %d(decimal): %.100s",
+                        myname, ch, name);
            return (0);
        }
     }
 
     if (non_numeric == 0) {
-       msg_warn("%s: numeric hostname: %.100s", myname, name);
+       if (gripe)
+           msg_warn("%s: numeric hostname: %.100s", myname, name);
        /* NOT: return (0); this confuses users of the DNS client */
     }
     if (cp - name > VALID_HOSTNAME_LEN) {
-       msg_warn("%s: bad length %d for %.100s...",
-                myname, (int) (cp - name), name);
+       if (gripe)
+           msg_warn("%s: bad length %d for %.100s...",
+                    myname, (int) (cp - name), name);
        return (0);
     }
     return (1);
@@ -114,7 +127,7 @@ int     valid_hostname(const char *name)
 
 /* valid_hostaddr - test dotted quad string for correctness */
 
-int     valid_hostaddr(const char *addr)
+int     valid_hostaddr(const char *addr, int gripe)
 {
     const char *cp;
     char   *myname = "valid_hostaddr";
@@ -129,7 +142,8 @@ int     valid_hostaddr(const char *addr)
      * Trivial cases first.
      */
     if (*addr == 0) {
-       msg_warn("%s: empty address", myname);
+       if (gripe)
+           msg_warn("%s: empty address", myname);
        return (0);
     }
 
@@ -146,28 +160,33 @@ int     valid_hostaddr(const char *addr)
            byte_val *= 10;
            byte_val += ch - '0';
            if (byte_val > 255) {
-               msg_warn("%s: invalid octet value: %.100s", myname, addr);
+               if (gripe)
+                   msg_warn("%s: invalid octet value: %.100s", myname, addr);
                return (0);
            }
        } else if (ch == '.') {
            if (in_byte == 0 || cp[1] == 0) {
-               msg_warn("%s: misplaced dot: %.100s", myname, addr);
+               if (gripe)
+                   msg_warn("%s: misplaced dot: %.100s", myname, addr);
                return (0);
            }
            if ((byte_count == 1 && byte_val == 0)) {
-               msg_warn("%s: bad initial octet value: %.100s", myname, addr);
+               if (gripe)
+                   msg_warn("%s: bad initial octet value: %.100s", myname, addr);
                return (0);
            }
            in_byte = 0;
        } else {
-           msg_warn("%s: invalid character %d(decimal): %.100s",
-                    myname, ch, addr);
+           if (gripe)
+               msg_warn("%s: invalid character %d(decimal): %.100s",
+                        myname, ch, addr);
            return (0);
        }
     }
 
     if (byte_count != BYTES_NEEDED) {
-       msg_warn("%s: invalid octet count: %.100s", myname, addr);
+       if (gripe)
+           msg_warn("%s: invalid octet count: %.100s", myname, addr);
        return (0);
     }
     return (1);
@@ -195,8 +214,8 @@ int     main(int unused_argc, char **argv)
 
     while (vstring_fgets_nonl(buffer, VSTREAM_IN)) {
        msg_info("testing: \"%s\"", vstring_str(buffer));
-       valid_hostname(vstring_str(buffer));
-       valid_hostaddr(vstring_str(buffer));
+       valid_hostname(vstring_str(buffer), DO_GRIPE);
+       valid_hostaddr(vstring_str(buffer), DO_GRIPE);
     }
     exit(0);
 }
index 69db140567069a3886d1b9536cf2e2a271481515..8de21619e2624d9b9cb6012c7b897c6a94366af0 100644 (file)
 #define VALID_HOSTNAME_LEN     255     /* RFC 1035 */
 #define VALID_LABEL_LEN                63      /* RFC 1035 */
 
-extern int valid_hostname(const char *);
-extern int valid_hostaddr(const char *);
+#define DONT_GRIPE             0
+#define DO_GRIPE               1
+
+extern int valid_hostname(const char *, int);
+extern int valid_hostaddr(const char *, int);
 
 /* LICENSE
 /* .ad
diff --git a/postfix/src/virtual/.indent.pro b/postfix/src/virtual/.indent.pro
deleted file mode 120000 (symlink)
index 5c837ec..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../.indent.pro
\ No newline at end of file
diff --git a/postfix/src/virtual/Makefile.in b/postfix/src/virtual/Makefile.in
deleted file mode 100644 (file)
index 9517501..0000000
+++ /dev/null
@@ -1,441 +0,0 @@
-SHELL  = /bin/sh
-SRCS   = virtual.c mailbox.c recipient.c deliver_attr.c maildir.c unknown.c
-OBJS   = virtual.o mailbox.o recipient.o deliver_attr.o maildir.o unknown.o
-HDRS   = virtual.h
-TESTSRC        =
-WARN   = -W -Wformat -Wimplicit -Wmissing-prototypes \
-       -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
-       -Wunused
-DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE) -I..
-CFLAGS = $(DEBUG) $(OPT) $(DEFS)
-PROG   = virtual
-TESTPROG= 
-INC_DIR        = ../../include
-LIBS   = ../../lib/libmaster.a ../../lib/libglobal.a ../../lib/libutil.a $(AUXLIBS)
-
-.c.o:; $(CC) $(CFLAGS) -c $*.c
-
-$(PROG):       $(OBJS) $(LIBS)
-       $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
-
-Makefile: Makefile.in
-       (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs; cat $?) >$@
-
-test:  $(TESTPROG)
-
-update: ../../libexec/$(PROG)
-
-../../libexec/$(PROG): $(PROG)
-       cp $(PROG) ../../libexec
-
-printfck: $(OBJS) $(PROG)
-       rm -rf printfck
-       mkdir printfck
-       cp *.h printfck
-       sed '1,/^# do not edit/!d' Makefile >printfck/Makefile
-       set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done
-       cd printfck; make "INC_DIR=../../include" `cd ..; ls *.o`
-
-lint:
-       lint $(DEFS) $(SRCS) $(LINTFIX)
-
-clean:
-       rm -f *.o *core $(PROG) $(TESTPROG) junk 
-       rm -rf printfck
-
-tidy:  clean
-
-depend: $(MAKES)
-       (sed '1,/^# do not edit/!d' Makefile.in; \
-       set -e; for i in [a-z][a-z0-9]*.c; do \
-           $(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-           -e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
-       done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
-       @make -f Makefile.in Makefile
-deliver_attr.o: deliver_attr.c
-deliver_attr.o: ../../include/sys_defs.h
-deliver_attr.o: ../../include/msg.h
-deliver_attr.o: ../../include/vstream.h
-deliver_attr.o: ../../include/vbuf.h
-deliver_attr.o: virtual.h
-deliver_attr.o: ../../include/htable.h
-deliver_attr.o: ../../include/vstring.h
-deliver_attr.o: ../../include/been_here.h
-deliver_attr.o: ../../include/tok822.h
-deliver_attr.o: ../../include/resolve_clnt.h
-deliver_attr.o: ../../include/deliver_request.h
-deliver_attr.o: ../../include/recipient_list.h
-deliver_attr.o: ../../include/maps.h
-deliver_attr.o: ../../include/dict.h
-deliver_attr.o: ../../include/argv.h
-mailbox.o: mailbox.c
-mailbox.o: ../../include/sys_defs.h
-mailbox.o: ../../include/msg.h
-mailbox.o: ../../include/htable.h
-mailbox.o: ../../include/vstring.h
-mailbox.o: ../../include/vbuf.h
-mailbox.o: ../../include/vstream.h
-mailbox.o: ../../include/mymalloc.h
-mailbox.o: ../../include/stringops.h
-mailbox.o: ../../include/set_eugid.h
-mailbox.o: ../../include/mail_copy.h
-mailbox.o: ../../include/safe_open.h
-mailbox.o: ../../include/deliver_flock.h
-mailbox.o: ../../include/dot_lockfile.h
-mailbox.o: ../../include/defer.h
-mailbox.o: ../../include/bounce.h
-mailbox.o: ../../include/sent.h
-mailbox.o: ../../include/mypwd.h
-mailbox.o: ../../include/mail_params.h
-mailbox.o: ../../include/deliver_pass.h
-mailbox.o: ../../include/deliver_request.h
-mailbox.o: ../../include/recipient_list.h
-mailbox.o: ../../include/mail_proto.h
-mailbox.o: ../../include/iostuff.h
-mailbox.o: virtual.h
-mailbox.o: ../../include/been_here.h
-mailbox.o: ../../include/tok822.h
-mailbox.o: ../../include/resolve_clnt.h
-mailbox.o: ../../include/maps.h
-mailbox.o: ../../include/dict.h
-mailbox.o: ../../include/argv.h
-maildir.o: maildir.c
-maildir.o: ../../include/sys_defs.h
-maildir.o: ../../include/msg.h
-maildir.o: ../../include/mymalloc.h
-maildir.o: ../../include/stringops.h
-maildir.o: ../../include/vstring.h
-maildir.o: ../../include/vbuf.h
-maildir.o: ../../include/vstream.h
-maildir.o: ../../include/make_dirs.h
-maildir.o: ../../include/set_eugid.h
-maildir.o: ../../include/get_hostname.h
-maildir.o: ../../include/mail_copy.h
-maildir.o: ../../include/bounce.h
-maildir.o: ../../include/sent.h
-maildir.o: ../../include/mail_params.h
-maildir.o: virtual.h
-maildir.o: ../../include/htable.h
-maildir.o: ../../include/been_here.h
-maildir.o: ../../include/tok822.h
-maildir.o: ../../include/resolve_clnt.h
-maildir.o: ../../include/deliver_request.h
-maildir.o: ../../include/recipient_list.h
-maildir.o: ../../include/maps.h
-maildir.o: ../../include/dict.h
-maildir.o: ../../include/argv.h
-recipient.o: recipient.c
-recipient.o: ../../include/sys_defs.h
-recipient.o: ../../include/msg.h
-recipient.o: ../../include/mymalloc.h
-recipient.o: ../../include/htable.h
-recipient.o: ../../include/split_at.h
-recipient.o: ../../include/stringops.h
-recipient.o: ../../include/vstring.h
-recipient.o: ../../include/vbuf.h
-recipient.o: ../../include/dict.h
-recipient.o: ../../include/vstream.h
-recipient.o: ../../include/argv.h
-recipient.o: ../../include/bounce.h
-recipient.o: ../../include/mail_params.h
-recipient.o: ../../include/split_addr.h
-recipient.o: ../../include/ext_prop.h
-recipient.o: virtual.h
-recipient.o: ../../include/been_here.h
-recipient.o: ../../include/tok822.h
-recipient.o: ../../include/resolve_clnt.h
-recipient.o: ../../include/deliver_request.h
-recipient.o: ../../include/recipient_list.h
-recipient.o: ../../include/maps.h
-unknown.o: unknown.c
-unknown.o: ../../include/sys_defs.h
-unknown.o: ../../include/msg.h
-unknown.o: ../../include/stringops.h
-unknown.o: ../../include/vstring.h
-unknown.o: ../../include/vbuf.h
-unknown.o: ../../include/mymalloc.h
-unknown.o: ../../include/mail_params.h
-unknown.o: ../../include/mail_proto.h
-unknown.o: ../../include/vstream.h
-unknown.o: ../../include/iostuff.h
-unknown.o: ../../include/bounce.h
-unknown.o: virtual.h
-unknown.o: ../../include/htable.h
-unknown.o: ../../include/been_here.h
-unknown.o: ../../include/tok822.h
-unknown.o: ../../include/resolve_clnt.h
-unknown.o: ../../include/deliver_request.h
-unknown.o: ../../include/recipient_list.h
-unknown.o: ../../include/maps.h
-unknown.o: ../../include/dict.h
-unknown.o: ../../include/argv.h
-virtual.o: virtual.c
-virtual.o: ../../include/sys_defs.h
-virtual.o: ../../include/msg.h
-virtual.o: ../../include/mymalloc.h
-virtual.o: ../../include/htable.h
-virtual.o: ../../include/vstring.h
-virtual.o: ../../include/vbuf.h
-virtual.o: ../../include/vstream.h
-virtual.o: ../../include/iostuff.h
-virtual.o: ../../include/name_mask.h
-virtual.o: ../../include/set_eugid.h
-virtual.o: ../../include/dict.h
-virtual.o: ../../include/argv.h
-virtual.o: ../../include/mail_queue.h
-virtual.o: ../../include/recipient_list.h
-virtual.o: ../../include/deliver_request.h
-virtual.o: ../../include/deliver_completed.h
-virtual.o: ../../include/mail_params.h
-virtual.o: ../../include/mail_addr.h
-virtual.o: ../../include/mail_conf.h
-virtual.o: ../../include/ext_prop.h
-virtual.o: ../../include/mail_server.h
-virtual.o: virtual.h
-virtual.o: ../../include/been_here.h
-virtual.o: ../../include/tok822.h
-virtual.o: ../../include/resolve_clnt.h
-virtual.o: ../../include/maps.h
-deliver_attr.o: deliver_attr.c
-deliver_attr.o: ../../include/sys_defs.h
-deliver_attr.o: ../../include/msg.h
-deliver_attr.o: ../../include/vstream.h
-deliver_attr.o: ../../include/vbuf.h
-deliver_attr.o: virtual.h
-deliver_attr.o: ../../include/vstring.h
-deliver_attr.o: ../../include/deliver_request.h
-deliver_attr.o: ../../include/recipient_list.h
-deliver_attr.o: ../../include/maps.h
-deliver_attr.o: ../../include/dict.h
-deliver_attr.o: ../../include/argv.h
-deliver_attr.o: ../../include/mbox_conf.h
-mailbox.o: mailbox.c
-mailbox.o: ../../include/sys_defs.h
-mailbox.o: ../../include/msg.h
-mailbox.o: ../../include/vstring.h
-mailbox.o: ../../include/vbuf.h
-mailbox.o: ../../include/vstream.h
-mailbox.o: ../../include/mymalloc.h
-mailbox.o: ../../include/stringops.h
-mailbox.o: ../../include/set_eugid.h
-mailbox.o: ../../include/mail_copy.h
-mailbox.o: ../../include/mbox_open.h
-mailbox.o: ../../include/safe_open.h
-mailbox.o: ../../include/defer.h
-mailbox.o: ../../include/bounce.h
-mailbox.o: ../../include/sent.h
-mailbox.o: ../../include/mypwd.h
-mailbox.o: ../../include/mail_params.h
-mailbox.o: virtual.h
-mailbox.o: ../../include/deliver_request.h
-mailbox.o: ../../include/recipient_list.h
-mailbox.o: ../../include/maps.h
-mailbox.o: ../../include/dict.h
-mailbox.o: ../../include/argv.h
-mailbox.o: ../../include/mbox_conf.h
-maildir.o: maildir.c
-maildir.o: ../../include/sys_defs.h
-maildir.o: ../../include/msg.h
-maildir.o: ../../include/mymalloc.h
-maildir.o: ../../include/stringops.h
-maildir.o: ../../include/vstring.h
-maildir.o: ../../include/vbuf.h
-maildir.o: ../../include/vstream.h
-maildir.o: ../../include/make_dirs.h
-maildir.o: ../../include/set_eugid.h
-maildir.o: ../../include/get_hostname.h
-maildir.o: ../../include/sane_fsops.h
-maildir.o: ../../include/mail_copy.h
-maildir.o: ../../include/bounce.h
-maildir.o: ../../include/sent.h
-maildir.o: ../../include/mail_params.h
-maildir.o: virtual.h
-maildir.o: ../../include/deliver_request.h
-maildir.o: ../../include/recipient_list.h
-maildir.o: ../../include/maps.h
-maildir.o: ../../include/dict.h
-maildir.o: ../../include/argv.h
-maildir.o: ../../include/mbox_conf.h
-recipient.o: recipient.c
-recipient.o: ../../include/sys_defs.h
-recipient.o: ../../include/msg.h
-recipient.o: ../../include/mymalloc.h
-recipient.o: ../../include/htable.h
-recipient.o: ../../include/split_at.h
-recipient.o: ../../include/stringops.h
-recipient.o: ../../include/vstring.h
-recipient.o: ../../include/vbuf.h
-recipient.o: ../../include/dict.h
-recipient.o: ../../include/vstream.h
-recipient.o: ../../include/argv.h
-recipient.o: ../../include/bounce.h
-recipient.o: ../../include/mail_params.h
-recipient.o: ../../include/split_addr.h
-recipient.o: ../../include/ext_prop.h
-recipient.o: virtual.h
-recipient.o: ../../include/deliver_request.h
-recipient.o: ../../include/recipient_list.h
-recipient.o: ../../include/maps.h
-recipient.o: ../../include/mbox_conf.h
-unknown.o: unknown.c
-unknown.o: ../../include/sys_defs.h
-unknown.o: ../../include/msg.h
-unknown.o: ../../include/stringops.h
-unknown.o: ../../include/vstring.h
-unknown.o: ../../include/vbuf.h
-unknown.o: ../../include/mymalloc.h
-unknown.o: ../../include/mail_params.h
-unknown.o: ../../include/mail_proto.h
-unknown.o: ../../include/vstream.h
-unknown.o: ../../include/iostuff.h
-unknown.o: ../../include/bounce.h
-unknown.o: virtual.h
-unknown.o: ../../include/deliver_request.h
-unknown.o: ../../include/recipient_list.h
-unknown.o: ../../include/maps.h
-unknown.o: ../../include/dict.h
-unknown.o: ../../include/argv.h
-unknown.o: ../../include/mbox_conf.h
-virtual.o: virtual.c
-virtual.o: ../../include/sys_defs.h
-virtual.o: ../../include/msg.h
-virtual.o: ../../include/mymalloc.h
-virtual.o: ../../include/htable.h
-virtual.o: ../../include/vstring.h
-virtual.o: ../../include/vbuf.h
-virtual.o: ../../include/vstream.h
-virtual.o: ../../include/iostuff.h
-virtual.o: ../../include/name_mask.h
-virtual.o: ../../include/set_eugid.h
-virtual.o: ../../include/dict.h
-virtual.o: ../../include/argv.h
-virtual.o: ../../include/mail_queue.h
-virtual.o: ../../include/recipient_list.h
-virtual.o: ../../include/deliver_request.h
-virtual.o: ../../include/deliver_completed.h
-virtual.o: ../../include/mail_params.h
-virtual.o: ../../include/mail_addr.h
-virtual.o: ../../include/mail_conf.h
-virtual.o: ../../include/mail_server.h
-virtual.o: virtual.h
-virtual.o: ../../include/maps.h
-virtual.o: ../../include/mbox_conf.h
-deliver_attr.o: deliver_attr.c
-deliver_attr.o: ../../include/sys_defs.h
-deliver_attr.o: ../../include/msg.h
-deliver_attr.o: ../../include/vstream.h
-deliver_attr.o: ../../include/vbuf.h
-deliver_attr.o: virtual.h
-deliver_attr.o: ../../include/vstring.h
-deliver_attr.o: ../../include/deliver_request.h
-deliver_attr.o: ../../include/recipient_list.h
-deliver_attr.o: ../../include/maps.h
-deliver_attr.o: ../../include/dict.h
-deliver_attr.o: ../../include/argv.h
-deliver_attr.o: ../../include/mbox_conf.h
-mailbox.o: mailbox.c
-mailbox.o: ../../include/sys_defs.h
-mailbox.o: ../../include/msg.h
-mailbox.o: ../../include/vstring.h
-mailbox.o: ../../include/vbuf.h
-mailbox.o: ../../include/vstream.h
-mailbox.o: ../../include/mymalloc.h
-mailbox.o: ../../include/stringops.h
-mailbox.o: ../../include/set_eugid.h
-mailbox.o: ../../include/mail_copy.h
-mailbox.o: ../../include/mbox_open.h
-mailbox.o: ../../include/safe_open.h
-mailbox.o: ../../include/defer.h
-mailbox.o: ../../include/bounce.h
-mailbox.o: ../../include/sent.h
-mailbox.o: ../../include/mypwd.h
-mailbox.o: ../../include/mail_params.h
-mailbox.o: virtual.h
-mailbox.o: ../../include/deliver_request.h
-mailbox.o: ../../include/recipient_list.h
-mailbox.o: ../../include/maps.h
-mailbox.o: ../../include/dict.h
-mailbox.o: ../../include/argv.h
-mailbox.o: ../../include/mbox_conf.h
-maildir.o: maildir.c
-maildir.o: ../../include/sys_defs.h
-maildir.o: ../../include/msg.h
-maildir.o: ../../include/mymalloc.h
-maildir.o: ../../include/stringops.h
-maildir.o: ../../include/vstring.h
-maildir.o: ../../include/vbuf.h
-maildir.o: ../../include/vstream.h
-maildir.o: ../../include/make_dirs.h
-maildir.o: ../../include/set_eugid.h
-maildir.o: ../../include/get_hostname.h
-maildir.o: ../../include/sane_fsops.h
-maildir.o: ../../include/mail_copy.h
-maildir.o: ../../include/bounce.h
-maildir.o: ../../include/sent.h
-maildir.o: ../../include/mail_params.h
-maildir.o: virtual.h
-maildir.o: ../../include/deliver_request.h
-maildir.o: ../../include/recipient_list.h
-maildir.o: ../../include/maps.h
-maildir.o: ../../include/dict.h
-maildir.o: ../../include/argv.h
-maildir.o: ../../include/mbox_conf.h
-recipient.o: recipient.c
-recipient.o: ../../include/sys_defs.h
-recipient.o: ../../include/msg.h
-recipient.o: ../../include/mymalloc.h
-recipient.o: ../../include/stringops.h
-recipient.o: ../../include/vstring.h
-recipient.o: ../../include/vbuf.h
-recipient.o: ../../include/bounce.h
-recipient.o: virtual.h
-recipient.o: ../../include/vstream.h
-recipient.o: ../../include/deliver_request.h
-recipient.o: ../../include/recipient_list.h
-recipient.o: ../../include/maps.h
-recipient.o: ../../include/dict.h
-recipient.o: ../../include/argv.h
-recipient.o: ../../include/mbox_conf.h
-unknown.o: unknown.c
-unknown.o: ../../include/sys_defs.h
-unknown.o: ../../include/msg.h
-unknown.o: ../../include/stringops.h
-unknown.o: ../../include/vstring.h
-unknown.o: ../../include/vbuf.h
-unknown.o: ../../include/mymalloc.h
-unknown.o: ../../include/mail_params.h
-unknown.o: ../../include/mail_proto.h
-unknown.o: ../../include/vstream.h
-unknown.o: ../../include/iostuff.h
-unknown.o: ../../include/bounce.h
-unknown.o: virtual.h
-unknown.o: ../../include/deliver_request.h
-unknown.o: ../../include/recipient_list.h
-unknown.o: ../../include/maps.h
-unknown.o: ../../include/dict.h
-unknown.o: ../../include/argv.h
-unknown.o: ../../include/mbox_conf.h
-virtual.o: virtual.c
-virtual.o: ../../include/sys_defs.h
-virtual.o: ../../include/msg.h
-virtual.o: ../../include/mymalloc.h
-virtual.o: ../../include/htable.h
-virtual.o: ../../include/vstring.h
-virtual.o: ../../include/vbuf.h
-virtual.o: ../../include/vstream.h
-virtual.o: ../../include/iostuff.h
-virtual.o: ../../include/name_mask.h
-virtual.o: ../../include/set_eugid.h
-virtual.o: ../../include/dict.h
-virtual.o: ../../include/argv.h
-virtual.o: ../../include/mail_queue.h
-virtual.o: ../../include/recipient_list.h
-virtual.o: ../../include/deliver_request.h
-virtual.o: ../../include/deliver_completed.h
-virtual.o: ../../include/mail_params.h
-virtual.o: ../../include/mail_addr.h
-virtual.o: ../../include/mail_conf.h
-virtual.o: ../../include/mail_server.h
-virtual.o: virtual.h
-virtual.o: ../../include/maps.h
-virtual.o: ../../include/mbox_conf.h
diff --git a/postfix/src/virtual/deliver_attr.c b/postfix/src/virtual/deliver_attr.c
deleted file mode 100644 (file)
index 63b1558..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*++
-/* NAME
-/*     deliver_attr 3
-/* SUMMARY
-/*     initialize message delivery attributes
-/* SYNOPSIS
-/*     #include "virtual.h"
-/*
-/*     void    deliver_attr_init(attrp)
-/*     DELIVER_ATTR *attrp;
-/*
-/*     void    deliver_attr_dump(attrp)
-/*     DELIVER_ATTR *attrp;
-/* DESCRIPTION
-/*     deliver_attr_init() initializes a structure with message delivery
-/*     attributes to a known initial state (all zeros).
-/*
-/*     deliver_attr_dump() logs the contents of the given attribute list.
-/* LICENSE
-/* .ad
-/* .fi
-/*     The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/*     Wietse Venema
-/*     IBM T.J. Watson Research
-/*     P.O. Box 704
-/*     Yorktown Heights, NY 10598, USA
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-
-/* Utility library. */
-
-#include <msg.h>
-#include <vstream.h>
-
-/* Application-specific. */
-
-#include "virtual.h"
-
-/* deliver_attr_init - set message delivery attributes to all-zero state */
-
-void    deliver_attr_init(DELIVER_ATTR *attrp)
-{
-    attrp->level = 0;
-    attrp->fp = 0;
-    attrp->queue_name = 0;
-    attrp->queue_id = 0;
-    attrp->offset = 0;
-    attrp->sender = 0;
-    attrp->recipient = 0;
-    attrp->user = 0;
-    attrp->delivered = 0;
-    attrp->relay = 0;
-}
-
-/* deliver_attr_dump - log message delivery attributes */
-
-void    deliver_attr_dump(DELIVER_ATTR *attrp)
-{
-    msg_info("level: %d", attrp->level);
-    msg_info("path: %s", VSTREAM_PATH(attrp->fp));
-    msg_info("fp: 0x%lx", (long) attrp->fp);
-    msg_info("queue_name: %s", attrp->queue_name ? attrp->queue_name : "null");
-    msg_info("queue_id: %s", attrp->queue_id ? attrp->queue_id : "null");
-    msg_info("offset: %ld", attrp->offset);
-    msg_info("sender: %s", attrp->sender ? attrp->sender : "null");
-    msg_info("recipient: %s", attrp->recipient ? attrp->recipient : "null");
-    msg_info("user: %s", attrp->user ? attrp->user : "null");
-    msg_info("delivered: %s", attrp->delivered ? attrp->delivered : "null");
-    msg_info("relay: %s", attrp->relay ? attrp->relay : "null");
-}
diff --git a/postfix/src/virtual/mailbox.c b/postfix/src/virtual/mailbox.c
deleted file mode 100644 (file)
index 9dfca28..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-/*++
-/* NAME
-/*     mailbox 3
-/* SUMMARY
-/*     mailbox delivery
-/* SYNOPSIS
-/*     #include "virtual.h"
-/*
-/*     int     deliver_mailbox(state, usr_attr, statusp)
-/*     LOCAL_STATE state;
-/*     USER_ATTR usr_attr;
-/*     int     *statusp;
-/* DESCRIPTION
-/*     deliver_mailbox() delivers to UNIX-style mailbox or to maildir.
-/*
-/*     A zero result means that the named user was not found.
-/*
-/*     Arguments:
-/* .IP state
-/*     The attributes that specify the message, recipient and more.
-/* .IP usr_attr
-/*     Attributes describing user rights and mailbox location.
-/* .IP statusp
-/*     Delivery status: see below.
-/* DIAGNOSTICS
-/*     The message delivery status is non-zero when delivery should be tried
-/*     again.
-/* LICENSE
-/* .ad
-/* .fi
-/*     The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/*     Wietse Venema
-/*     IBM T.J. Watson Research
-/*     P.O. Box 704
-/*     Yorktown Heights, NY 10598, USA
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <errno.h>
-
-/* Utility library. */
-
-#include <msg.h>
-#include <vstring.h>
-#include <vstream.h>
-#include <mymalloc.h>
-#include <stringops.h>
-#include <set_eugid.h>
-
-/* Global library. */
-
-#include <mail_copy.h>
-#include <mbox_open.h>
-#include <defer.h>
-#include <sent.h>
-#include <mail_params.h>
-
-#ifndef EDQUOT
-#define EDQUOT EFBIG
-#endif
-
-/* Application-specific. */
-
-#include "virtual.h"
-
-#define YES    1
-#define NO     0
-
-/* deliver_mailbox_file - deliver to recipient mailbox */
-
-static int deliver_mailbox_file(LOCAL_STATE state, USER_ATTR usr_attr)
-{
-    char   *myname = "deliver_mailbox_file";
-    VSTRING *why;
-    MBOX   *mp;
-    int     status;
-    int     copy_flags;
-    long    end;
-    struct stat st;
-
-    /*
-     * Make verbose logging easier to understand.
-     */
-    state.level++;
-    if (msg_verbose)
-       MSG_LOG_STATE(myname, state);
-
-    /*
-     * Initialize. Assume the operation will fail. Set the delivered
-     * attribute to reflect the final recipient.
-     */
-    if (vstream_fseek(state.msg_attr.fp, state.msg_attr.offset, SEEK_SET) < 0)
-       msg_fatal("seek message file %s: %m", VSTREAM_PATH(state.msg_attr.fp));
-    state.msg_attr.delivered = state.msg_attr.recipient;
-    status = -1;
-    why = vstring_alloc(100);
-
-    /*
-     * Lock the mailbox and open/create the mailbox file.
-     * 
-     * Write the file as the recipient, so that file quota work.
-     */
-    copy_flags = MAIL_COPY_MBOX;
-
-    set_eugid(usr_attr.uid, usr_attr.gid);
-    mp = mbox_open(usr_attr.mailbox, O_APPEND | O_WRONLY | O_CREAT,
-                  S_IRUSR | S_IWUSR, &st, -1, -1,
-                  virtual_mbox_lock_mask, why);
-    if (mp != 0) {
-       if (S_ISREG(st.st_mode) == 0) {
-           vstream_fclose(mp->fp);
-           vstring_sprintf(why, "destination is not a regular file");
-           errno = 0;
-       } else {
-           end = vstream_fseek(mp->fp, (off_t) 0, SEEK_END);
-           status = mail_copy(COPY_ATTR(state.msg_attr), mp->fp,
-                              copy_flags, "\n", why);
-       }
-       mbox_release(mp);
-    }
-    set_eugid(var_owner_uid, var_owner_gid);
-
-    /*
-     * As the mail system, bounce, defer delivery, or report success.
-     */
-    if (status != 0)
-       status = (errno == EDQUOT ? bounce_append : defer_append)
-           (BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
-            "cannot access mailbox for %s. %s",
-            usr_attr.mailbox, state.msg_attr.recipient, vstring_str(why));
-    else
-       sent(SENT_ATTR(state.msg_attr), "mailbox");
-
-    vstring_free(why);
-    return (status);
-}
-
-/* deliver_mailbox - deliver to recipient mailbox */
-
-int     deliver_mailbox(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp)
-{
-    char   *myname = "deliver_mailbox";
-    const char *result;
-    long    n;
-
-    /*
-     * Make verbose logging easier to understand.
-     */
-    state.level++;
-    if (msg_verbose)
-       MSG_LOG_STATE(myname, state);
-
-    /*
-     * Sanity check.
-     */
-    if (*var_virt_mailbox_base != '/')
-       msg_fatal("do not specify relative pathname: %s = %s",
-                 VAR_VIRT_MAILBOX_BASE, var_virt_mailbox_base);
-
-    /*
-     * Look up the mailbox location and rights of the recipient user.
-     */
-    result = maps_find(virtual_mailbox_maps, state.msg_attr.user, 0);
-    if (result == 0) {
-       if (dict_errno == 0)
-           return (NO);
-
-       *statusp = defer_append(BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
-                               "%s: lookup %s: %m",
-                         virtual_mailbox_maps->title, state.msg_attr.user);
-       return (YES);
-    }
-    usr_attr.mailbox = concatenate(var_virt_mailbox_base, "/", result, (char *) 0);
-
-    if ((result = maps_find(virtual_uid_maps, state.msg_attr.user, 0)) == 0) {
-       myfree(usr_attr.mailbox);
-       *statusp = defer_append(BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
-                               "recipient %s: uid not found in %s",
-                             state.msg_attr.user, virtual_uid_maps->title);
-       return (YES);
-    }
-    if ((n = atol(result)) < var_virt_minimum_uid) {
-       myfree(usr_attr.mailbox);
-       *statusp = defer_append(BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
-                               "recipient %s: bad uid %s in %s",
-                     state.msg_attr.user, result, virtual_uid_maps->title);
-       return (YES);
-    }
-    usr_attr.uid = (uid_t) n;
-
-    if ((result = maps_find(virtual_gid_maps, state.msg_attr.user, 0)) == 0) {
-       myfree(usr_attr.mailbox);
-       *statusp = defer_append(BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
-                               "recipient %s: gid not found in %s",
-                             state.msg_attr.user, virtual_gid_maps->title);
-       return (YES);
-    }
-    if ((n = atol(result)) <= 0) {
-       myfree(usr_attr.mailbox);
-       *statusp = defer_append(BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
-                               "recipient %s: bad gid %s in %s",
-                     state.msg_attr.user, result, virtual_gid_maps->title);
-       return (YES);
-    }
-    usr_attr.gid = (gid_t) n;
-
-    if (msg_verbose)
-       msg_info("%s[%d]: set user_attr: %s, uid = %d, gid = %d",
-                myname, state.level,
-                usr_attr.mailbox, usr_attr.uid, usr_attr.gid);
-
-    /*
-     * Deliver to mailbox or to external command.
-     */
-#define LAST_CHAR(s) (s[strlen(s) - 1])
-
-    if (LAST_CHAR(usr_attr.mailbox) == '/')
-       *statusp = deliver_maildir(state, usr_attr);
-    else
-       *statusp = deliver_mailbox_file(state, usr_attr);
-
-    /*
-     * Cleanup.
-     */
-    myfree(usr_attr.mailbox);
-    return (YES);
-}
diff --git a/postfix/src/virtual/maildir.c b/postfix/src/virtual/maildir.c
deleted file mode 100644 (file)
index 4aa0c67..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/*++
-/* NAME
-/*     maildir 3
-/* SUMMARY
-/*     delivery to maildir
-/* SYNOPSIS
-/*     #include "virtual.h"
-/*
-/*     int     deliver_maildir(state, usr_attr)
-/*     LOCAL_STATE state;
-/*     USER_ATTR usr_attr;
-/* DESCRIPTION
-/*     deliver_maildir() delivers a message to a qmail-style maildir.
-/*
-/*     Arguments:
-/* .IP state
-/*     The attributes that specify the message, recipient and more.
-/* .IP usr_attr
-/*     Attributes describing user rights and environment information.
-/* DIAGNOSTICS
-/*     deliver_maildir() always succeeds or it bounces the message.
-/* SEE ALSO
-/*     bounce(3)
-/* LICENSE
-/* .ad
-/* .fi
-/*     The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/*     Wietse Venema
-/*     IBM T.J. Watson Research
-/*     P.O. Box 704
-/*     Yorktown Heights, NY 10598, USA
-/*--*/
-
-/* System library. */
-
-#include "sys_defs.h"
-#include <errno.h>
-
-/* Utility library. */
-
-#include <msg.h>
-#include <mymalloc.h>
-#include <stringops.h>
-#include <vstream.h>
-#include <vstring.h>
-#include <make_dirs.h>
-#include <set_eugid.h>
-#include <get_hostname.h>
-#include <sane_fsops.h>
-
-/* Global library. */
-
-#include <mail_copy.h>
-#include <bounce.h>
-#include <sent.h>
-#include <mail_params.h>
-
-/* Application-specific. */
-
-#include "virtual.h"
-
-/* deliver_maildir - delivery to maildir-style mailbox */
-
-int     deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr)
-{
-    char   *myname = "deliver_maildir";
-    char   *newdir;
-    char   *tmpdir;
-    char   *curdir;
-    char   *tmpfile;
-    char   *newfile;
-    VSTRING *why;
-    VSTRING *buf;
-    VSTREAM *dst;
-    int     status;
-    int     copy_flags;
-    static int count;
-
-    /*
-     * Make verbose logging easier to understand.
-     */
-    state.level++;
-    if (msg_verbose)
-       MSG_LOG_STATE(myname, state);
-
-    /*
-     * Initialize. Assume the operation will fail. Set the delivered
-     * attribute to reflect the final recipient.
-     */
-    if (vstream_fseek(state.msg_attr.fp, state.msg_attr.offset, SEEK_SET) < 0)
-       msg_fatal("seek message file %s: %m", VSTREAM_PATH(state.msg_attr.fp));
-    state.msg_attr.delivered = state.msg_attr.recipient;
-    status = -1;
-    buf = vstring_alloc(100);
-    why = vstring_alloc(100);
-
-    copy_flags = MAIL_COPY_TOFILE | MAIL_COPY_RETURN_PATH | MAIL_COPY_DELIVERED;
-
-    newdir = concatenate(usr_attr.mailbox, "new/", (char *) 0);
-    tmpdir = concatenate(usr_attr.mailbox, "tmp/", (char *) 0);
-    curdir = concatenate(usr_attr.mailbox, "cur/", (char *) 0);
-
-    /*
-     * Create and write the file as the recipient, so that file quota work.
-     * Create any missing directories on the fly. The file name is chosen
-     * according to ftp://koobera.math.uic.edu/www/proto/maildir.html:
-     * 
-     * "A unique name has three pieces, separated by dots. On the left is the
-     * result of time(). On the right is the result of gethostname(). In the
-     * middle is something that doesn't repeat within one second on a single
-     * host. I fork a new process for each delivery, so I just use the
-     * process ID. If you're delivering several messages from one process,
-     * use starttime.pid_count.host, where starttime is the time that your
-     * process started, and count is the number of messages you've
-     * delivered."
-     */
-#define STR vstring_str
-
-    set_eugid(usr_attr.uid, usr_attr.gid);
-    vstring_sprintf(buf, "%ld.%d_%d.%s", (long) var_starttime,
-                   var_pid, count++, get_hostname());
-    tmpfile = concatenate(tmpdir, STR(buf), (char *) 0);
-    newfile = concatenate(newdir, STR(buf), (char *) 0);
-    if ((dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0
-       && (errno != ENOENT
-           || make_dirs(tmpdir, 0700) < 0
-           || (dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0)) {
-       vstring_sprintf(why, "create %s: %m", tmpfile);
-    } else {
-       if (mail_copy(COPY_ATTR(state.msg_attr), dst, copy_flags, "\n", why) == 0) {
-           if (sane_link(tmpfile, newfile) < 0
-               && (errno != ENOENT
-                   || (make_dirs(curdir, 0700), make_dirs(newdir, 0700)) < 0
-                   || sane_link(tmpfile, newfile) < 0)) {
-               vstring_sprintf(why, "link to %s: %m", newfile);
-           } else {
-               status = 0;
-           }
-       }
-       if (unlink(tmpfile) < 0)
-           msg_warn("remove %s: %m", tmpfile);
-    }
-    set_eugid(var_owner_uid, var_owner_gid);
-
-    if (status)
-       bounce_append(BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
-                     "maildir delivery failed: %s", vstring_str(why));
-    else
-       sent(SENT_ATTR(state.msg_attr), "maildir");
-    vstring_free(buf);
-    vstring_free(why);
-    myfree(newdir);
-    myfree(tmpdir);
-    myfree(curdir);
-    myfree(tmpfile);
-    myfree(newfile);
-    return (0);
-}
diff --git a/postfix/src/virtual/recipient.c b/postfix/src/virtual/recipient.c
deleted file mode 100644 (file)
index 725108f..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*++
-/* NAME
-/*     recipient 3
-/* SUMMARY
-/*     deliver to one local recipient
-/* SYNOPSIS
-/*     #include "virtual.h"
-/*
-/*     int     deliver_recipient(state, usr_attr)
-/*     LOCAL_STATE state;
-/*     USER_ATTR *usr_attr;
-/* DESCRIPTION
-/*     deliver_recipient() delivers a message to a local recipient.
-/*
-/*     Arguments:
-/* .IP state
-/*     The attributes that specify the message, sender, and more.
-/* .IP usr_attr
-/*     Attributes describing user rights and mailbox location.
-/* DIAGNOSTICS
-/*     deliver_recipient() returns non-zero when delivery should be
-/*     tried again.
-/* SEE ALSO
-/*     mailbox(3) delivery to UNIX-style mailbox
-/*     maildir(3) delivery to qmail-style maildir
-/* LICENSE
-/* .ad
-/* .fi
-/*     The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/*     Wietse Venema
-/*     IBM T.J. Watson Research
-/*     P.O. Box 704
-/*     Yorktown Heights, NY 10598, USA
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-
-/* Utility library. */
-
-#include <msg.h>
-#include <mymalloc.h>
-#include <stringops.h>
-
-/* Global library. */
-
-#include <bounce.h>
-
-/* Application-specific. */
-
-#include "virtual.h"
-
-/* deliver_recipient - deliver one local recipient */
-
-int     deliver_recipient(LOCAL_STATE state, USER_ATTR usr_attr)
-{
-    char   *myname = "deliver_recipient";
-    int     rcpt_stat;
-
-    /*
-     * Make verbose logging easier to understand.
-     */
-    state.level++;
-    if (msg_verbose)
-       MSG_LOG_STATE(myname, state);
-
-    /*
-     * Set up the recipient-specific attributes. The recipient's lookup
-     * handle is the full address.
-     */
-    if (state.msg_attr.delivered == 0)
-       state.msg_attr.delivered = state.msg_attr.recipient;
-    state.msg_attr.user = mystrdup(state.msg_attr.recipient);
-    lowercase(state.msg_attr.user);
-
-    /*
-     * Deliver
-     */
-    if (msg_verbose)
-       deliver_attr_dump(&state.msg_attr);
-
-    if (deliver_mailbox(state, usr_attr, &rcpt_stat) == 0)
-       rcpt_stat = deliver_unknown(state);
-
-    /*
-     * Cleanup.
-     */
-    myfree(state.msg_attr.user);
-
-    return (rcpt_stat);
-}
diff --git a/postfix/src/virtual/unknown.c b/postfix/src/virtual/unknown.c
deleted file mode 100644 (file)
index 8989046..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*++
-/* NAME
-/*     unknown 3
-/* SUMMARY
-/*     delivery of unknown recipients
-/* SYNOPSIS
-/*     #include "virtual.h"
-/*
-/*     int     deliver_unknown(state)
-/*     LOCAL_STATE state;
-/* DESCRIPTION
-/*     deliver_unknown() delivers a message for unknown recipients.
-/* .PP
-/*     Arguments:
-/* .IP state
-/*     Message delivery attributes (sender, recipient etc.).
-/* .IP usr_attr
-/*     Attributes describing user rights and mailbox location.
-/* DIAGNOSTICS
-/*     The result status is non-zero when delivery should be tried again.
-/* LICENSE
-/* .ad
-/* .fi
-/*     The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/*     Wietse Venema
-/*     IBM T.J. Watson Research
-/*     P.O. Box 704
-/*     Yorktown Heights, NY 10598, USA
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-
-/* Utility library. */
-
-#include <msg.h>
-
-/* Global library. */
-
-#include <bounce.h>
-
-/* Application-specific. */
-
-#include "virtual.h"
-
-/* deliver_unknown - delivery for unknown recipients */
-
-int     deliver_unknown(LOCAL_STATE state)
-{
-    char   *myname = "deliver_unknown";
-
-    /*
-     * Make verbose logging easier to understand.
-     */
-    state.level++;
-    if (msg_verbose)
-       MSG_LOG_STATE(myname, state);
-
-    return (bounce_append(BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
-                         "unknown user: \"%s\"", state.msg_attr.user));
-
-}
diff --git a/postfix/src/virtual/virtual b/postfix/src/virtual/virtual
deleted file mode 100755 (executable)
index bde19ec..0000000
Binary files a/postfix/src/virtual/virtual and /dev/null differ
diff --git a/postfix/src/virtual/virtual.c b/postfix/src/virtual/virtual.c
deleted file mode 100644 (file)
index 87a71d3..0000000
+++ /dev/null
@@ -1,392 +0,0 @@
-/*++
-/* NAME
-/*     virtual 8
-/* SUMMARY
-/*     Postfix virtual domain mail delivery agent
-/* SYNOPSIS
-/*     \fBvirtual\fR [generic Postfix daemon options]
-/* DESCRIPTION
-/*     The \fBvirtual\fR delivery agent is designed for virtual mail 
-/*     hosting services. Originally based on the Postfix local delivery 
-/*     agent, this agent looks up recipients with map lookups of their 
-/*     full recipient address, instead of using hard-coded unix password 
-/*     file lookups of the address local part only. 
-/*
-/*     This delivery agent only delivers mail.  Other features such as 
-/*     mail forwarding, out-of-office notifications, etc., must be 
-/*     configured via virtual maps or via similar lookup mechanisms.
-/* MAILBOX LOCATION
-/* .ad
-/* .fi
-/*     The mailbox location is controlled by the \fBvirtual_mailbox_base\fR
-/*     and \fBvirtual_mailbox_maps\fR configuration parameters (see below).
-/*     The pathname is constructed as follows:
-/*
-/* .ti +2
-/*     \fB$virtual_mailbox_base/$virtual_mailbox_maps(\fIrecipient\fB)\fR
-/*
-/*     where \fIrecipient\fR is the full recipient address.
-/* UNIX MAILBOX FORMAT
-/* .ad
-/* .fi
-/*     When the mailbox location does not end in \fB/\fR, the message
-/*     is delivered in UNIX mailbox format.   This format stores multiple
-/*     messages in one textfile.
-/*
-/*     The \fBvirtual\fR delivery agent prepends a "\fBFrom \fIsender 
-/*     time_stamp\fR" envelope header to each message, prepends a 
-/*     \fBDelivered-To:\fR message header with the envelope recipient 
-/*     address, prepends a \fBReturn-Path:\fR message header with the 
-/*     envelope sender address, prepends a \fB>\fR character to lines 
-/*     beginning with "\fBFrom \fR", and appends an empty line.
-/*
-/*     The mailbox is locked for exclusive access while delivery is in
-/*     progress. In case of problems, an attempt is made to truncate the
-/*     mailbox to its original length.
-/* QMAIL MAILDIR FORMAT
-/* .ad
-/* .fi
-/*     When the mailbox location ends in \fB/\fR, the message is delivered
-/*     in qmail \fBmaildir\fR format. This format stores one message per file.
-/*
-/*     The \fBvirtual\fR delivery agent daemon prepends a \fBDelivered-To:\fR 
-/*     message header with the envelope recipient address and prepends a 
-/*     \fBReturn-Path:\fR message header with the envelope sender address.
-/*
-/*     By definition, \fBmaildir\fR format does not require file locking
-/*     during mail delivery or retrieval.
-/* MAILBOX OWNERSHIP
-/* .ad
-/* .fi
-/*     Mailbox ownership is controlled by the \fBvirtual_owner_maps\fR
-/*     lookup tables. These tables can perform the following mappings:
-/* .IP "recipient      username"
-/*     The mailbox is owned by the specified UNIX user.
-/* .IP "recipient      uid:gid"
-/*     The mailbox is owned by the specified numerical user and group ID.
-/* BACKWARDS COMPATIBILITY
-/* .ad
-/* .fi
-/*     For backwards compatibility, mailbox ownership can also be specified
-/*     through separate \fBvirtual_uid_maps\fR and \fBvirtual_gid_maps\fR
-/*     tables.
-/* SAFETY
-/* .ad
-/* .fi
-/*     The \fBvirtual_minimum_uid\fR parameter imposes a lower bound on 
-/*     numerical user ID values that may be specified in any 
-/*     \fBvirtual_owner_maps\fR or \fBvirtual_uid_maps\fR.
-/* STANDARDS
-/*     RFC 822 (ARPA Internet Text Messages)
-/* DIAGNOSTICS
-/*     Mail bounces when the recipient has no mailbox or when the
-/*     recipient is over disk quota. In all other cases, mail for
-/*     an existing recipient is deferred and a warning is logged.
-/*
-/*     Problems and transactions are logged to \fBsyslogd\fR(8).
-/*     Corrupted message files are marked so that the queue
-/*     manager can move them to the \fBcorrupt\fR queue afterwards.
-/*
-/*     Depending on the setting of the \fBnotify_classes\fR parameter,
-/*     the postmaster is notified of bounces and of other trouble.
-/* BUGS
-/*     This delivery agent silently ignores address extensions.
-/* CONFIGURATION PARAMETERS
-/* .ad
-/* .fi
-/*     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 Mailbox delivery
-/* .ad
-/* .fi
-/* .IP \fBvirtual_mailbox_base\fR
-/*     Specifies a path that is prepended to all mailbox or maildir paths.
-/*     This is a safety measure to ensure that an out of control map in
-/*     \fBvirtual_mailbox_maps\fR doesn't litter the filesystem with mailboxes.
-/*     While it could be set to "/", this setting isn't recommended.
-/* .IP \fBvirtual_mailbox_maps\fR
-/*     Recipients are looked up in these maps to determine the path to
-/*     their mailbox or maildir. If the returned path ends in a slash
-/*     ("/"), maildir-style delivery is carried out, otherwise the
-/*     path is assumed to specify a mailbox file.
-/*
-/*     Note that \fBvirtual_mailbox_base\fR is unconditionally prepended
-/*     to this path.
-/* .IP \fBvirtual_minimum_uid\fR
-/*     Specifies a minimum uid that will be accepted as a return from
-/*     a \fBvirtual_owner_maps\fR or \fBvirtual_uid_maps\fR lookup. 
-/*     Returned values less than this will be rejected, and the message 
-/*     will be deferred.
-/* .IP \fBvirtual_owner_maps\fR
-/*     Recipients are looked up in these maps to determine the UNIX user
-/*     name of the mailbox owner, or the numerical user and group ID
-/*     in numerical \fIuid:gid\fR format.
-/* .IP \fBvirtual_uid_maps\fR
-/*     Recipients are looked up in these maps to determine the user ID to be
-/*     used when writing to the target mailbox.
-/* .sp
-/*     This feature exists for backwards compatibility; it will go away.
-/* .IP \fBvirtual_gid_maps\fR
-/*     Recipients are looked up in these maps to determine the group ID to be
-/*     used when writing to the target mailbox.
-/* .sp
-/*     This feature exists for backwards compatibility; it will go away.
-/* .SH "Locking controls"
-/* .ad
-/* .fi
-/* .IP \fBmailbox_delivery_lock\fR
-/*     How to lock UNIX-style mailboxes: one or more of \fBflock\fR,
-/*     \fBfcntl\fR or \fBdotlock\fR.
-/*
-/*     Use the command \fBpostconf -m\fR to find out what locking methods
-/*     are available on your system.
-/* .IP \fBdeliver_lock_attempts\fR
-/*     Limit the number of attempts to acquire an exclusive lock
-/*     on a UNIX-style mailbox file.
-/* .IP \fBdeliver_lock_delay\fR
-/*     Time (default: seconds) between successive attempts to acquire
-/*     an exclusive lock on a UNIX-style mailbox file.
-/* .IP \fBstale_lock_time\fR
-/*     Limit the time after which a stale lockfile is removed (applicable
-/*     to UNIX-style mailboxes only).
-/* .SH "Resource controls"
-/* .ad
-/* .fi
-/* .IP \fBvirtual_destination_concurrency_limit\fR
-/*     Limit the number of parallel deliveries to the same domain.
-/*     The default limit is taken from the
-/*     \fBdefault_destination_concurrency_limit\fR parameter.
-/* .IP \fBvirtual_destination_recipient_limit\fR
-/*     Limit the number of recipients per message delivery.
-/*     The default limit is taken from the
-/*     \fBdefault_destination_recipient_limit\fR parameter.
-/* HISTORY
-/* .ad
-/* .fi
-/*     This agent was originally based on the Postfix local delivery
-/*     agent. Modifications mainly consisted of removing code that either
-/*     was not applicable or that was not safe in this context: aliases,
-/*     ~user/.forward files, delivery to "|command" or to /file/name.
-/*
-/*     The \fBDelivered-To:\fR header appears in the \fBqmail\fR system
-/*     by Daniel Bernstein.
-/*
-/*     The \fImaildir\fR structure appears in the \fBqmail\fR system
-/*     by Daniel Bernstein.
-/* SEE ALSO
-/*     bounce(8) non-delivery status reports
-/*     syslogd(8) system logging
-/*     qmgr(8) queue manager
-/* LICENSE
-/* .ad
-/* .fi
-/*     The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/*     Wietse Venema
-/*     IBM T.J. Watson Research
-/*     P.O. Box 704
-/*     Yorktown Heights, NY 10598, USA
-/*
-/*     Andrew McNamara
-/*     andrewm@connect.com.au
-/*     connect.com.au Pty. Ltd.
-/*     Level 3, 213 Miller St
-/*     North Sydney 2060, NSW, Australia
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-
-/* Utility library. */
-
-#include <msg.h>
-#include <vstring.h>
-#include <vstream.h>
-#include <iostuff.h>
-#include <set_eugid.h>
-#include <dict.h>
-
-/* Global library. */
-
-#include <mail_queue.h>
-#include <recipient_list.h>
-#include <deliver_request.h>
-#include <deliver_completed.h>
-#include <mail_params.h>
-#include <mail_conf.h>
-#include <mail_params.h>
-
-/* Single server skeleton. */
-
-#include <mail_server.h>
-
-/* Application-specific. */
-
-#include "virtual.h"
-
- /*
-  * Tunable parameters.
-  */
-char   *var_mailbox_maps;
-char   *var_uid_maps;
-char   *var_gid_maps;
-int     var_virt_minimum_uid;
-char   *var_virt_mailbox_base;
-char   *var_mailbox_lock;
-
- /*
-  * Mappings.
-  */
-MAPS   *virtual_mailbox_maps;
-MAPS   *virtual_uid_maps;
-MAPS   *virtual_gid_maps;
-
- /*
-  * Bit masks.
-  */
-int     virtual_mbox_lock_mask;
-
-/* local_deliver - deliver message with extreme prejudice */
-
-static int local_deliver(DELIVER_REQUEST *rqst, char *service)
-{
-    char   *myname = "local_deliver";
-    RECIPIENT *rcpt_end = rqst->rcpt_list.info + rqst->rcpt_list.len;
-    RECIPIENT *rcpt;
-    int     rcpt_stat;
-    int     msg_stat;
-    LOCAL_STATE state;
-    USER_ATTR usr_attr;
-
-    if (msg_verbose)
-       msg_info("local_deliver: %s from %s", rqst->queue_id, rqst->sender);
-
-    /*
-     * Initialize the delivery attributes that are not recipient specific.
-     * While messages are being delivered and while aliases or forward files
-     * are being expanded, this attribute list is being changed constantly.
-     * For this reason, the list is passed on by value (except when it is
-     * being initialized :-), so that there is no need to undo attribute
-     * changes made by lower-level routines. The alias/include/forward
-     * expansion attribute list is part of a tree with self and parent
-     * references (see the EXPAND_ATTR definitions). The user-specific
-     * attributes are security sensitive, and are therefore kept separate.
-     * All this results in a noticeable level of clumsiness, but passing
-     * things around by value gives good protection against accidental change
-     * by subroutines.
-     */
-    state.level = 0;
-    deliver_attr_init(&state.msg_attr);
-    state.msg_attr.queue_name = rqst->queue_name;
-    state.msg_attr.queue_id = rqst->queue_id;
-    state.msg_attr.fp = rqst->fp;
-    state.msg_attr.offset = rqst->data_offset;
-    state.msg_attr.sender = rqst->sender;
-    state.msg_attr.relay = service;
-    state.msg_attr.arrival_time = rqst->arrival_time;
-    RESET_USER_ATTR(usr_attr, state.level);
-    state.request = rqst;
-
-    /*
-     * Iterate over each recipient named in the delivery request. When the
-     * mail delivery status for a given recipient is definite (i.e. bounced
-     * or delivered), update the message queue file and cross off the
-     * recipient. Update the per-message delivery status.
-     */
-    for (msg_stat = 0, rcpt = rqst->rcpt_list.info; rcpt < rcpt_end; rcpt++) {
-       state.msg_attr.recipient = rcpt->address;
-       rcpt_stat = deliver_recipient(state, usr_attr);
-       if (rcpt_stat == 0)
-           deliver_completed(state.msg_attr.fp, rcpt->offset);
-       msg_stat |= rcpt_stat;
-    }
-
-    return (msg_stat);
-}
-
-/* local_service - perform service for client */
-
-static void local_service(VSTREAM *stream, char *service, char **argv)
-{
-    DELIVER_REQUEST *request;
-    int     status;
-
-    /*
-     * Sanity check. This service takes no command-line arguments.
-     */
-    if (argv[0])
-       msg_fatal("unexpected command-line argument: %s", argv[0]);
-
-    /*
-     * This routine runs whenever a client connects to the UNIX-domain socket
-     * that is dedicated to local mail delivery service. What we see below is
-     * a little protocol to (1) tell the client that we are ready, (2) read a
-     * delivery request from the client, and (3) report the completion status
-     * of that request.
-     */
-    if ((request = deliver_request_read(stream)) != 0) {
-       status = local_deliver(request, service);
-       deliver_request_done(stream, request, status);
-    }
-}
-
-/* pre_accept - see if tables have changed */
-
-static void pre_accept(char *unused_name, char **unused_argv)
-{
-    if (dict_changed()) {
-       msg_info("table has changed -- exiting");
-       exit(0);
-    }
-}
-
-/* post_init - post-jail initialization */
-
-static void post_init(char *unused_name, char **unused_argv)
-{
-
-    /*
-     * Drop privileges most of the time.
-     */
-    set_eugid(var_owner_uid, var_owner_gid);
-
-    virtual_mailbox_maps =
-       maps_create(VAR_VIRT_MAILBOX_MAPS, var_mailbox_maps,
-                   DICT_FLAG_LOCK);
-
-    virtual_uid_maps =
-       maps_create(VAR_VIRT_UID_MAPS, var_uid_maps, DICT_FLAG_LOCK);
-
-    virtual_gid_maps =
-       maps_create(VAR_VIRT_UID_MAPS, var_gid_maps, DICT_FLAG_LOCK);
-
-    virtual_mbox_lock_mask = mbox_lock_mask(var_mailbox_lock);
-}
-
-/* main - pass control to the single-threaded skeleton */
-
-int     main(int argc, char **argv)
-{
-    static CONFIG_INT_TABLE int_table[] = {
-       VAR_VIRT_MINUID, DEF_VIRT_MINUID, &var_virt_minimum_uid, 1, 0,
-       0,
-    };
-    static CONFIG_STR_TABLE str_table[] = {
-       VAR_VIRT_MAILBOX_MAPS, DEF_VIRT_MAILBOX_MAPS, &var_mailbox_maps, 0, 0,
-       VAR_VIRT_UID_MAPS, DEF_VIRT_UID_MAPS, &var_uid_maps, 0, 0,
-       VAR_VIRT_GID_MAPS, DEF_VIRT_GID_MAPS, &var_gid_maps, 0, 0,
-       VAR_VIRT_MAILBOX_BASE, DEF_VIRT_MAILBOX_BASE, &var_virt_mailbox_base, 0, 0,
-       VAR_MAILBOX_LOCK, DEF_MAILBOX_LOCK, &var_mailbox_lock, 1, 0,
-       0,
-    };
-
-    single_server_main(argc, argv, local_service,
-                      MAIL_SERVER_INT_TABLE, int_table,
-                      MAIL_SERVER_STR_TABLE, str_table,
-                      MAIL_SERVER_POST_INIT, post_init,
-                      MAIL_SERVER_PRE_ACCEPT, pre_accept,
-                      0);
-}
diff --git a/postfix/src/virtual/virtual.h b/postfix/src/virtual/virtual.h
deleted file mode 100644 (file)
index 1443bc8..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*++
-/* NAME
-/*     virtual 3h
-/* SUMMARY
-/*     virtual mail delivery
-/* SYNOPSIS
-/*     #include "virtual.h"
-/* DESCRIPTION
-/* .nf
-
- /*
-  * System library.
-  */
-#include <unistd.h>
-
- /*
-  * Utility library.
-  */
-#include <vstream.h>
-#include <vstring.h>
-
- /*
-  * Global library.
-  */
-#include <deliver_request.h>
-#include <maps.h>
-#include <mbox_conf.h>
-
- /*
-  * Mappings.
-  */
-extern MAPS *virtual_mailbox_maps;
-extern MAPS *virtual_uid_maps;
-extern MAPS *virtual_gid_maps;
-
- /*
-  * User attributes: these control the privileges for delivery to external
-  * commands, external files, or mailboxes, and the initial environment of
-  * external commands.
-  */
-typedef struct USER_ATTR {
-    uid_t   uid;                       /* file/command access */
-    gid_t   gid;                       /* file/command access */
-    char   *mailbox;                   /* mailbox file or directory */
-} USER_ATTR;
-
- /*
-  * Critical macros. Not for obscurity, but to ensure consistency.
-  */
-#define RESET_USER_ATTR(usr_attr, level) { \
-       usr_attr.uid = 0; usr_attr.gid = 0; usr_attr.mailbox = 0; \
-       if (msg_verbose) \
-           msg_info("%s[%d]: reset user_attr", myname, level); \
-    }
-
- /*
-  * The delivery attributes are inherited from files, from aliases, and from
-  * whatnot. Some of the information is changed on the fly. DELIVER_ATTR
-  * structres are therefore passed by value, so there is no need to undo
-  * changes.
-  */
-typedef struct DELIVER_ATTR {
-    int     level;                     /* recursion level */
-    VSTREAM *fp;                       /* open queue file */
-    char   *queue_name;                        /* mail queue id */
-    char   *queue_id;                  /* mail queue id */
-    long    offset;                    /* data offset */
-    char   *sender;                    /* taken from envelope */
-    char   *recipient;                 /* taken from resolver */
-    char   *user;                      /* recipient lookup handle */
-    char   *delivered;                 /* for loop detection */
-    char   *relay;                     /* relay host */
-    long    arrival_time;              /* arrival time */
-} DELIVER_ATTR;
-
-extern void deliver_attr_init(DELIVER_ATTR *);
-extern void deliver_attr_dump(DELIVER_ATTR *);
-
-#define FEATURE_NODELIVERED    (1<<0)  /* no delivered-to */
-
- /*
-  * Rather than schlepping around dozens of arguments, here is one that has
-  * all. Well, almost. The user attributes are just a bit too sensitive, so
-  * they are passed around separately.
-  */
-typedef struct LOCAL_STATE {
-    int     level;                     /* nesting level, for logging */
-    DELIVER_ATTR msg_attr;             /* message attributes */
-    DELIVER_REQUEST *request;          /* as from queue manager */
-} LOCAL_STATE;
-
- /*
-  * Bundle up some often-user attributes.
-  */
-#define BOUNCE_ATTR(attr)      attr.queue_id, attr.recipient, attr.relay, \
-                                       attr.arrival_time
-#define SENT_ATTR(attr)                attr.queue_id, attr.recipient, attr.relay, \
-                                       attr.arrival_time
-#define COPY_ATTR(attr)                attr.sender, attr.delivered, attr.fp
-
-#define MSG_LOG_STATE(m, p) \
-       msg_info("%s[%d]: recip %s deliver %s", m, \
-                p.level, \
-               p.msg_attr.recipient ? p.msg_attr.recipient : "", \
-               p.msg_attr.delivered ? p.msg_attr.delivered : "")
-
- /*
-  * "inner" nodes of the delivery graph.
-  */
-extern int deliver_recipient(LOCAL_STATE, USER_ATTR);
-
- /*
-  * "leaf" nodes of the delivery graph.
-  */
-extern int deliver_mailbox(LOCAL_STATE, USER_ATTR, int *);
-extern int deliver_file(LOCAL_STATE, USER_ATTR, char *);
-extern int deliver_maildir(LOCAL_STATE, USER_ATTR);
-extern int deliver_unknown(LOCAL_STATE);
-
- /*
-  * Mailbox lock protocol.
-  */
-extern int virtual_mbox_lock_mask;
-
-/* LICENSE
-/* .ad
-/* .fi
-/*     The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/*     Wietse Venema
-/*     IBM T.J. Watson Research
-/*     P.O. Box 704
-/*     Yorktown Heights, NY 10598, USA
-/*--*/