diff --git a/postfix/FILTER_README b/postfix/FILTER_README index 5c8c495c0..243c2f4c9 100644 --- a/postfix/FILTER_README +++ b/postfix/FILTER_README @@ -60,23 +60,20 @@ The filter program can start out as a simple shell script like this: # Exit codes from EX_TEMPFAIL=75 EX_UNAVAILABLE=69 - STATUS=$EX_TEMPFAIL # Clean up when done or when aborting. - trap "rm -f in.$$; exit $STATUS" 0 1 2 3 15 - - quit() { STATUS=${1-$?}; exit; } + trap "rm -f in.$$" 0 1 2 3 15 # Start processing. - cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; quit $EX_TEMPFAIL; } + cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; } - cat >in.$$ || { echo Cannot save mail to file; quit $EX_TEMPFAIL; } + cat >in.$$ || { echo Cannot save mail to file; exit $EX_TEMPFAIL; } - # filter and adapted to -snapshot 20001121 by Xavier Beaudouin. - -Code is maintened now by Xavier Beaudouin - -[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: ---/--- - - diff --git a/postfix/conf/sample-compatibility.cf b/postfix/conf/sample-compatibility.cf new file mode 100644 index 000000000..329ee4cf3 --- /dev/null +++ b/postfix/conf/sample-compatibility.cf @@ -0,0 +1,66 @@ +# 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 compatibility with broken software. + +# The ignore_mx_lookup_error parameter controls what happens when a +# name server fails to respond to an MX lookup request. By default, +# Postfix defers delivery and tries again after some delay. Specify +# "ignore_mx_lookup_error = yes" to force an A record lookup instead. +# +ignore_mx_lookup_error = no + +# The smtp_always_send_ehlo parameter specifies that the SMTP client +# should always send EHLO at the start of an SMTP session. +# +# By default, Postfix sends EHLO only when the word "ESMTP" appears +# in the server greeting banner (example: 220 spike.porcupine.org +# ESMTP Postfix). +# +smtp_always_send_ehlo = no + +# The smtp_never_send_ehlo parameter specifies that the SMTP client +# should never send EHLO at the start of an SMTP session. +# +# By default, Postfix sends EHLO whenever the word "ESMTP" appears +# in the server greeting banner (example: 220 spike.porcupine.org +# ESMTP Postfix). +# +smtp_never_send_ehlo = no + +# The smtp_skip_4xx_greeting parameter controls what happens when +# an SMTP server greets us with a 4XX status code (go away, try +# again later). +# +# By default, Postfix moves on the the next mail exchanger. Specify +# "smtp_skip_4xx_greeting = no" if Postfix should defer delivery +# immediately. +# +smtp_skip_4xx_greeting = yes + +# The smtp_skip_5xx_greeting parameter controls what happens when +# an SMTP server greets us with a 5XX status code (go away, do not +# try again later). +# +# By default, Postfix moves on the the next mail exchanger. Specify +# "smtp_skip_5xx_greeting = no" if Postfix should bounce the mail +# immediately. +# +smtp_skip_5xx_greeting = yes + +# The smtp_skip_quit_response parameter controls whether the SMTP +# client waits for the response to the QUIT command. The default is +# to not wait. +# +smtp_skip_quit_response = yes + +# The strict_rfc821_envelopes configuration parameter controls whether +# the Postfix SMTP server requires that MAIL FROM and RCPT TO addresses +# are specified within <>, and that MAIL FROM and RCPT TO addresses +# do not contain RFC822-style comments or phrases. It's great to +# stop SPAM mailers. But it also trips up broken peecee clients. +# +# By default, Postfix SMTPD allows RFC822 syntax in MAIL FROM and RCPT TO. +# +strict_rfc821_envelopes = no diff --git a/postfix/conf/sample-smtp.cf b/postfix/conf/sample-smtp.cf index 0750e0f21..ccaf5ec64 100644 --- a/postfix/conf/sample-smtp.cf +++ b/postfix/conf/sample-smtp.cf @@ -66,11 +66,24 @@ smtp_never_send_ehlo = no #smtp_bind_address=111.222.333.444 # The smtp_skip_4xx_greeting parameter controls what happens when -# an SMTP server greets us with a 4XX status code. By default, Postfix -# backs off. Specify "smtp_skip_4xx_greeting = yes" to move on the -# the next mail exchanger. -# -smtp_skip_4xx_greeting = no +# an SMTP server greets us with a 4XX status code (go away, try +# again later). +# +# By default, Postfix moves on the the next mail exchanger. Specify +# "smtp_skip_4xx_greeting = no" if Postfix should defer delivery +# immediately. +# +smtp_skip_4xx_greeting = yes + +# The smtp_skip_5xx_greeting parameter controls what happens when +# an SMTP server greets us with a 5XX status code (go away, do not +# try again later). +# +# By default, Postfix moves on the the next mail exchanger. Specify +# "smtp_skip_5xx_greeting = no" if Postfix should bounce the mail +# immediately. +# +smtp_skip_5xx_greeting = yes # The smtp_skip_quit_response parameter controls whether the SMTP # client waits for the response to the QUIT command. The default is diff --git a/postfix/conf/sample-smtpd.cf b/postfix/conf/sample-smtpd.cf index 02df49246..56f301800 100644 --- a/postfix/conf/sample-smtpd.cf +++ b/postfix/conf/sample-smtpd.cf @@ -63,6 +63,16 @@ smtpd_recipient_limit = 1000 # smtpd_timeout = 300s +# The strict_rfc821_envelopes configuration parameter controls whether +# the Postfix SMTP server requires that MAIL FROM and RCPT TO addresses +# are specified within <>, and that MAIL FROM and RCPT TO addresses +# do not contain RFC822-style comments or phrases. It's great to +# stop SPAM mailers. But it also trips up broken peecee clients. +# +# By default, Postfix SMTPD allows RFC822 syntax in MAIL FROM and RCPT TO. +# +strict_rfc821_envelopes = no + # # TARPIT CONTROLS # diff --git a/postfix/examples/chroot-setup/LINUX2 b/postfix/examples/chroot-setup/LINUX2 index 78aaab251..dc9419db1 100644 --- a/postfix/examples/chroot-setup/LINUX2 +++ b/postfix/examples/chroot-setup/LINUX2 @@ -1,9 +1,14 @@ #! /bin/sh # LINUX2 - shell script to set up a Postfix chroot jail for Linux -# Tested on SuSE Linux 5.3 (libc5) and 6.4 (glibc2.1) +# Tested on SuSE Linux 5.3 (libc5) and 7.0 (glibc2.1) -# Copyright (c) 2000 by Matthias Andree +# Other testers reported as working: +# +# 2001-01-15 Debian sid (unstable) +# Christian Kurz + +# Copyright (c) 2000 - 2001 by Matthias Andree # Redistributable unter the MIT-style license that follows: # Abstract: "do whatever you want except hold somebody liable or change # the copyright information". @@ -26,14 +31,29 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. +# 2000-09-29 +# v0.1: initial release + +# 2000-12-05 +# v0.2: copy libdb.* for libnss_db.so +# remove /etc/localtime in case it's a broken symlink +# restrict find to maxdepth 1 (faster) + +# $Log: LINUX2,v $ +# Revision 1.4 2001/01/15 09:36:35 emma +# add note it was successfully tested on Debian sid +# + +CP="cp -p" + cond_copy() { # find files as per pattern in $1 # if any, copy to directory $2 dir=`dirname "$1"` pat=`basename "$1"` - lr=`find "$dir" -name "$pat"` + lr=`find "$dir" -maxdepth 1 -name "$pat"` if test ! -d "$2" ; then exit 1 ; fi - if test "x$lr" != "x" ; then cp -p $1 "$2" ; fi + if test "x$lr" != "x" ; then $CP $1 "$2" ; fi } set -e @@ -47,10 +67,18 @@ mkdir -p etc lib usr/lib/zoneinfo # find localtime (SuSE 5.3 does not have /etc/localtime) lt=/etc/localtime if test ! -f $lt ; then lt=/usr/lib/zoneinfo/localtime ; fi +if test ! -f $lt ; then lt=/usr/share/zoneinfo/localtime ; fi if test ! -f $lt ; then echo "cannot find localtime" ; exit 1 ; fi -cp -p -f $lt /etc/services /etc/resolv.conf /etc/nsswitch.conf etc -cp -p -f /etc/host.conf /etc/hosts /etc/passwd etc +rm -f etc/localtime + +# copy localtime and some other system files into the chroot's etc +$CP -f $lt /etc/services /etc/resolv.conf /etc/nsswitch.conf etc +$CP -f /etc/host.conf /etc/hosts /etc/passwd etc ln -s -f /etc/localtime usr/lib/zoneinfo -cond_copy '/lib/libnss_*' lib -cond_copy '/lib/libresolv*' lib \ No newline at end of file +# copy required libraries into the chroot +cond_copy '/lib/libnss_*.so*' lib +cond_copy '/lib/libresolv.so*' lib +cond_copy '/lib/libdb.so*' lib + +postfix reload diff --git a/postfix/html/Makefile.in b/postfix/html/Makefile.in index c15b21a1f..8a342e1fc 100644 --- a/postfix/html/Makefile.in +++ b/postfix/html/Makefile.in @@ -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 \ - nqmgr.8.html spawn.8.html flush.8.html virtual.8.html + nqmgr.8.html spawn.8.html flush.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 \ @@ -81,9 +81,6 @@ smtpd.8.html: ../src/smtpd/smtpd.c trivial-rewrite.8.html: ../src/trivial-rewrite/trivial-rewrite.c srctoman $? | nroff -man | man2html | postlink >$@ -virtual.8.html: ../src/virtual/virtual.c - srctoman $? | nroff -man | man2html | postlink >$@ - postalias.1.html: ../src/postalias/postalias.c srctoman $? | nroff -man | man2html | postlink >$@ diff --git a/postfix/html/lmtp.8.html b/postfix/html/lmtp.8.html index 25ff4baf0..c68540a97 100644 --- a/postfix/html/lmtp.8.html +++ b/postfix/html/lmtp.8.html @@ -73,6 +73,7 @@ LMTP(8) LMTP(8) RFC 2033 (LMTP protocol) RFC 2197 (Pipelining) + RFC 2554 (AUTH command) DIAGNOSTICS Problems and transactions are logged to syslogd(8). Cor- @@ -119,12 +120,11 @@ LMTP(8) LMTP(8) server. Used as backup if the lmtp service is not found in services(4). -Resource controls - lmtp_cache_connection - 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 +Authentication controls + lmtp_enable_sasl_auth + Enable per-session authentication as per RFC 2554 + (SASL). By default, Postfix is built without SASL + support. @@ -137,6 +137,35 @@ LMTP(8) LMTP(8) LMTP(8) LMTP(8) + lmtp_sasl_password_maps + Lookup tables with per-host or domain name:password + entries. No entry for a host means no attempt to + authenticate. + + lmtp_sasl_security_options + Zero or more of the following. + + noplaintext + Disallow authentication methods that use + plaintext passwords. + + noactive + Disallow authentication methods that are + vulnerable to non-dictionary active attacks. + + nodictionary + Disallow authentication methods that are + vulnerable to passive dictionary attack. + + noanonymous + Disallow anonymous logins. + +Resource controls + lmtp_cache_connection + 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: @@ -162,6 +191,18 @@ LMTP(8) LMTP(8) destination via this mail delivery transport. transport is the name of the service as specified in the master.cf file. The default limit is taken + + + + 3 + + + + + +LMTP(8) LMTP(8) + + from the default_destination_concurrency_limit parameter. @@ -192,17 +233,6 @@ LMTP(8) LMTP(8) value: s (seconds), m (minutes), h (hours), d (days) or w (weeks). - - - 3 - - - - - -LMTP(8) LMTP(8) - - lmtp_connect_timeout Timeout for opening a connection to the LMTP server. If no connection can be made within the @@ -227,6 +257,18 @@ LMTP(8) LMTP(8) lmtp_data_xfer_timeout Timeout for sending the message content. + + + + 4 + + + + + +LMTP(8) LMTP(8) + + lmtp_data_done_timeout Timeout for sending the "." command, and for receiving the server response. When no response is @@ -257,18 +299,6 @@ LMTP(8) LMTP(8) AUTHOR(S) Wietse Venema IBM T.J. Watson Research - - - - 4 - - - - - -LMTP(8) LMTP(8) - - P.O. Box 704 Yorktown Heights, NY 10598, USA @@ -296,36 +326,6 @@ LMTP(8) LMTP(8) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 diff --git a/postfix/html/smtpd.8.html b/postfix/html/smtpd.8.html index c81578a9b..a6fe58de5 100644 --- a/postfix/html/smtpd.8.html +++ b/postfix/html/smtpd.8.html @@ -77,6 +77,11 @@ SMTPD(8) SMTPD(8) For example, allow RFC822-style address forms with comments, like Sendmail does. + allow_broken_auth_clients + 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". + Content inspection controls content_filter The name of a mail delivery transport that filters @@ -119,11 +124,6 @@ SMTPD(8) SMTPD(8) Location of Postfix support commands (default: $program_directory). - debug_peer_level - Increment in verbose logging level when a remote - host matches a pattern in the debug_peer_list - parameter. - @@ -137,6 +137,11 @@ SMTPD(8) SMTPD(8) SMTPD(8) SMTPD(8) + debug_peer_level + Increment in verbose logging level when a remote + host matches a pattern in the debug_peer_list + parameter. + debug_peer_list List of domain or network patterns. When a remote host matches a pattern, increase the verbose log- @@ -186,11 +191,6 @@ SMTPD(8) SMTPD(8) reject responses. This can be useful for testing purposes. -Resource controls - line_length_limit - Limit the amount of memory in bytes used for the - handling of partial input lines. - @@ -203,6 +203,11 @@ SMTPD(8) SMTPD(8) SMTPD(8) SMTPD(8) +Resource controls + line_length_limit + Limit the amount of memory in bytes used for the + handling of partial input lines. + message_size_limit Limit the total size in bytes of a message, includ- ing on-disk storage for envelope information. @@ -253,11 +258,6 @@ SMTPD(8) SMTPD(8) Restrict what recipient addresses are allowed in RCPT TO commands. - smtpd_etrn_restrictions - Restrict what domain names can be used in ETRN com- - mands, and what clients may issue ETRN commands. - - 4 @@ -269,6 +269,10 @@ SMTPD(8) SMTPD(8) SMTPD(8) SMTPD(8) + smtpd_etrn_restrictions + Restrict what domain names can be used in ETRN com- + mands, and what clients may issue ETRN commands. + allow_untrusted_routing Allow untrusted clients to specify addresses with sender-specified routing. Enabling this opens up @@ -319,10 +323,6 @@ SMTPD(8) SMTPD(8) name mapping violates the reject_unknown_clients restriction. - unknown_hostname_reject_code - Server response when a client violates the - reject_unknown_hostname restriction. - @@ -335,6 +335,10 @@ SMTPD(8) SMTPD(8) SMTPD(8) SMTPD(8) + unknown_hostname_reject_code + Server response when a client violates the + reject_unknown_hostname restriction. + SEE ALSO cleanup(8) message canonicalization master(8) process manager @@ -383,10 +387,6 @@ SMTPD(8) SMTPD(8) - - - - diff --git a/postfix/html/virtual.8.html b/postfix/html/virtual.8.html deleted file mode 100644 index 5f5aafb9d..000000000 --- a/postfix/html/virtual.8.html +++ /dev/null @@ -1,266 +0,0 @@ -
-
-
-
-VIRTUAL(8)                                             VIRTUAL(8)
-
-
-NAME
-       virtual - Postfix virtual domain mail delivery agent
-
-SYNOPSIS
-       virtual [generic Postfix daemon options]
-
-DESCRIPTION
-       This  daemon  is  designed for ISP's offering virtual mail
-       hosting services. Originally based on the  local  delivery
-       agent,  this  agent locates user mailboxes via map lookups
-       of the full recipient address, rather than hard-coded unix
-       password file searches of the local part only.
-
-       The  virtual  daemon  processes delivery requests from the
-       Postfix queue manager to deliver  mail  to  virtual  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 master(8) process manager.
-
-       The virtual daemon updates queue files and  marks  recipi-
-       ents  as  finished,  or  it informs the queue manager that
-       delivery should be tried again at a later  time.  Delivery
-       problem reports are sent to the bounce(8) or defer(8) dae-
-       mon as appropriate.
-
-MAILBOX DELIVERY
-       The virtual delivery agent can deliver to UNIX-style mail-
-       box file or to qmail-style maildir files. The pathname and
-       delivery mailbox style are controlled by the virtual_mail-
-       box_base and virtual_mailbox_maps configuration parameters
-       (see below).
-
-       In the case of UNIX-style mailbox delivery, the local dae-
-       mon prepends a "From sender time_stamp" envelope header to
-       each message, prepends a  Delivered-To:  header  with  the
-       envelope recipient address, prepends a Return-Path: header
-       with the envelope sender address, prepends a  >  character
-       to  lines  beginning  with  "From  ", 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.
-
-       In the case of maildir delivery, the local daemon prepends
-       a Delivered-To: header with the envelope recipient address
-       and prepends  a  Return-Path:  header  with  the  envelope
-       sender address.
-
-DELIVERY RIGHTS
-       Deliveries  are  made  with  the user and group privileges
-       that are listed in the  tables  specified  with  the  vir-
-       tual_uid_maps and virtual_gid_maps, respectively.
-
-       The  virtual_minimum_uid parameter specifies a lower bound
-
-
-
-                                                                1
-
-
-
-
-
-VIRTUAL(8)                                             VIRTUAL(8)
-
-
-       on  user  ID  values  that  may  be  specified   in   vir-
-       tual_uid_maps.  Mail  will not be delivered when a too low
-       UID value is found.
-
-STANDARDS
-       RFC 822 (ARPA Internet Text Messages)
-
-DIAGNOSTICS
-       Problems and transactions are logged to syslogd(8).   Cor-
-       rupted  message files are marked so that the queue manager
-       can move them to the corrupt queue afterwards.
-
-       Depending on the setting of the notify_classes  parameter,
-       the  postmaster  is notified of bounces and of other trou-
-       ble.
-
-CONFIGURATION PARAMETERS
-       The following main.cf parameters are  especially  relevant
-       to  this  program. See the Postfix main.cf file for syntax
-       details and for default values.  Use  the  postfix  reload
-       command after a configuration change.
-
-Mailbox delivery
-       virtual_mailbox_base
-              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 virtual_mail-
-              box_maps doesn't litter the filesystem  with  mail-
-              boxes.   While it could be set to "/", this setting
-              isn't recommended.
-
-       virtual_mailbox_maps
-              Recipients are looked up in this map  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 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 mail-
-              box.
-
-       virtual_gid_maps
-              Recipients are looked up in this map  to  determine
-
-
-
-                                                                2
-
-
-
-
-
-VIRTUAL(8)                                             VIRTUAL(8)
-
-
-              the GID to be used when writing to the target mail-
-              box.
-
-Locking controls
-       mailbox_delivery_lock
-              How to lock UNIX-style mailboxes: one  or  more  of
-              flock, fcntl or dotlock.
-
-              Use  the command postconf -m to find out what lock-
-              ing methods are available on your system.
-
-       deliver_lock_attempts
-              Limit the number of attempts to acquire  an  exclu-
-              sive lock on a mailbox file.
-
-       deliver_lock_delay
-              Time (default: seconds) between successive attempts
-              to acquire an exclusive lock on a mailbox file.
-
-       stale_lock_time
-              Limit the time after  which  a  stale  lockfile  is
-              removed.
-
-Resource controls
-       virtual_destination_concurrency_limit
-              Limit the number of parallel deliveries to the same
-              domain.   The  default  limit  is  taken  from  the
-              default_destination_concurrency_limit parameter.
-
-       virtual_destination_recipient_limit
-              Limit  the  number of recipients per message deliv-
-              ery.   The  default  limit  is   taken   from   the
-              default_destination_recipient_limit parameter.
-
-HISTORY
-       This  agent  was  originally  based  on the local delivery
-       agent. Modifications mainly  consisted  of  removing  code
-       that  wasn't  applicable  or  wasn't  safe in this context
-       (aliases, .forwards, program aliases).
-
-       The Delivered-To: header appears in the  qmail  system  by
-       Daniel Bernstein.
-
-       The  maildir  structure  appears  in  the  qmail system by
-       Daniel Bernstein.
-
-SEE ALSO
-       bounce(8) non-delivery status reports
-       syslogd(8) system logging
-       qmgr(8) queue manager
-
-LICENSE
-       The Secure Mailer license must be  distributed  with  this
-       software.
-
-
-
-                                                                3
-
-
-
-
-
-VIRTUAL(8)                                             VIRTUAL(8)
-
-
-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
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-                                                                4
-
-
-
diff --git a/postfix/man/Makefile.in b/postfix/man/Makefile.in index 8ea0fe0fd..8e258047d 100644 --- a/postfix/man/Makefile.in +++ b/postfix/man/Makefile.in @@ -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/nqmgr.8 man8/spawn.8 man8/flush.8 man8/virtual.8 + man8/nqmgr.8 man8/spawn.8 man8/flush.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 \ @@ -80,9 +80,6 @@ man8/smtpd.8: ../src/smtpd/smtpd.c man8/trivial-rewrite.8: ../src/trivial-rewrite/trivial-rewrite.c ../mantools/srctoman $? >$@ -man8/virtual.8: ../src/virtual/virtual.c - ../mantools/srctoman $? >$@ - man1/postalias.1: ../src/postalias/postalias.c ../mantools/srctoman $? >$@ diff --git a/postfix/man/man8/lmtp.8 b/postfix/man/man8/lmtp.8 index 3fe89ed12..bca8c187c 100644 --- a/postfix/man/man8/lmtp.8 +++ b/postfix/man/man8/lmtp.8 @@ -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 diff --git a/postfix/man/man8/smtpd.8 b/postfix/man/man8/smtpd.8 index 832e3e19d..f8eccc0cb 100644 --- a/postfix/man/man8/smtpd.8 +++ b/postfix/man/man8/smtpd.8 @@ -71,6 +71,10 @@ 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 +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". .SH "Content inspection controls" .IP \fBcontent_filter\fR The name of a mail delivery transport that filters mail and that diff --git a/postfix/man/man8/virtual.8 b/postfix/man/man8/virtual.8 deleted file mode 100644 index 79849c37d..000000000 --- a/postfix/man/man8/virtual.8 +++ /dev/null @@ -1,183 +0,0 @@ -.TH VIRTUAL 8 -.ad -.fi -.SH NAME -virtual -\- -Postfix virtual domain mail delivery agent -.SH SYNOPSIS -.na -.nf -\fBvirtual\fR [generic Postfix daemon options] -.SH DESCRIPTION -.ad -.fi -This daemon is designed for ISP's offering virtual mail hosting -services. Originally based on the local delivery agent, this agent -locates user mailboxes via map lookups of the full recipient -address, rather than hard-coded unix password file searches of -the local part only. - -The \fBvirtual\fR daemon processes delivery requests from the -Postfix queue manager to deliver mail to virtual 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 \fBmaster\fR(8) process -manager. - -The \fBvirtual\fR daemon updates queue files and marks recipients -as finished, or it informs the queue manager that delivery should -be tried again at a later time. Delivery problem reports are sent -to the \fBbounce\fR(8) or \fBdefer\fR(8) daemon as appropriate. -.SH MAILBOX DELIVERY -.na -.nf -.ad -.fi -The \fBvirtual\fR delivery agent can deliver to UNIX-style mailbox -file or to qmail-style maildir files. The pathname and delivery -mailbox style are controlled by the \fBvirtual_mailbox_base\fR -and \fBvirtual_mailbox_maps\fR configuration parameters (see below). - -In the case of UNIX-style mailbox delivery, -the \fBlocal\fR daemon prepends a "\fBFrom \fIsender time_stamp\fR" -envelope header to each message, prepends a \fBDelivered-To:\fR header -with the envelope recipient address, prepends a \fBReturn-Path:\fR -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. - -In the case of \fBmaildir\fR delivery, the local daemon prepends -a \fBDelivered-To:\fR header with the envelope recipient address -and prepends a \fBReturn-Path:\fR header with the envelope sender -address. -.SH DELIVERY RIGHTS -.na -.nf -.ad -.fi -Deliveries are made with the user and group privileges that are -listed in the tables specified with the \fBvirtual_uid_maps\fR -and \fBvirtual_gid_maps\fR, respectively. - -The \fBvirtual_minimum_uid\fR parameter specifies a lower bound on -user ID values that may be specified in \fBvirtual_uid_maps\fR. Mail -will not be delivered when a too low UID value is found. -.SH STANDARDS -.na -.nf -RFC 822 (ARPA Internet Text Messages) -.SH DIAGNOSTICS -.ad -.fi -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. -.SH CONFIGURATION PARAMETERS -.na -.nf -.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 this map 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_uid_maps\fR lookup. Returned values less than this -will be rejected, and the message will be deferred. -.IP \fBvirtual_uid_maps\fR -Recipients are looked up in this map to determine the UID to be -used when writing to the target mailbox. -.IP \fBvirtual_gid_maps\fR -Recipients are looked up in this map to determine the GID to be -used when writing to the target mailbox. -.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 mailbox file. -.IP \fBdeliver_lock_delay\fR -Time (default: seconds) between successive attempts to acquire -an exclusive lock on a mailbox file. -.IP \fBstale_lock_time\fR -Limit the time after which a stale lockfile is removed. -.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. -.SH HISTORY -.na -.nf -.ad -.fi -This agent was originally based on the local delivery -agent. Modifications mainly consisted of removing code that wasn't -applicable or wasn't safe in this context (aliases, .forwards, -program aliases). - -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. -.SH SEE ALSO -.na -.nf -bounce(8) non-delivery status reports -syslogd(8) system logging -qmgr(8) queue manager -.SH LICENSE -.na -.nf -.ad -.fi -The Secure Mailer license must be distributed with this software. -.SH AUTHOR(S) -.na -.nf -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 diff --git a/postfix/src/base64/.indent.pro b/postfix/src/base64/.indent.pro deleted file mode 120000 index 5c837eca6..000000000 --- a/postfix/src/base64/.indent.pro +++ /dev/null @@ -1 +0,0 @@ -../../.indent.pro \ No newline at end of file diff --git a/postfix/src/base64/Makefile.in b/postfix/src/base64/Makefile.in deleted file mode 100644 index 08a2e4915..000000000 --- a/postfix/src/base64/Makefile.in +++ /dev/null @@ -1,79 +0,0 @@ -SHELL = /bin/sh -SRCS = base64encode.c base64decode.c -OBJS = base64encode.o base64decode.o -HDRS = -TESTSRC = -WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \ - -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \ - -Wunused -DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE) -CFLAGS = $(DEBUG) $(OPT) $(DEFS) -TESTPROG= -INC_DIR = ../../include -PROG = base64encode base64decode -LIBS = ../../lib/libglobal.a ../../lib/libutil.a - -.c.o:; $(CC) $(CFLAGS) -c $*.c - -all: $(PROG) - -Makefile: Makefile.in - (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@ - -base64decode: base64decode.o $(LIBS) - $(CC) $(CFLAGS) -o $@ base64decode.o $(LIBS) $(SYSLIBS) - -base64encode: base64encode.o $(LIBS) - $(CC) $(CFLAGS) -o $@ base64encode.o $(LIBS) $(SYSLIBS) - -test: $(TESTPROG) - -update: ../../bin/base64encode ../../bin/base64decode - -../../bin/base64encode: base64encode - cp $? $@ - -../../bin/base64decode: base64decode - cp $? $@ - -printfck: $(OBJS) $(PROG) - rm -rf printfck - mkdir 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 - @$(EXPORT) make -f Makefile.in Makefile 1>&2 - -# do not edit below this line - it is generated by 'make depend' -base64decode.o: base64decode.c -base64decode.o: ../../include/sys_defs.h -base64decode.o: ../../include/vstring.h -base64decode.o: ../../include/vbuf.h -base64decode.o: ../../include/vstream.h -base64decode.o: ../../include/vstring_vstream.h -base64decode.o: ../../include/msg.h -base64decode.o: ../../include/msg_vstream.h -base64encode.o: base64encode.c -base64encode.o: ../../include/sys_defs.h -base64encode.o: ../../include/vstring.h -base64encode.o: ../../include/vbuf.h -base64encode.o: ../../include/vstream.h -base64encode.o: ../../include/vstring_vstream.h -base64encode.o: ../../include/msg.h -base64encode.o: ../../include/msg_vstream.h diff --git a/postfix/src/base64/base64decode.c b/postfix/src/base64/base64decode.c deleted file mode 100644 index 14602ad20..000000000 --- a/postfix/src/base64/base64decode.c +++ /dev/null @@ -1,63 +0,0 @@ -/* base64decode - transform base 64 data to printable form */ - -/* System library. */ - -#include -#include - -/* SASL library. */ - -#include -#include - -/* Utility library. */ - -#include -#include -#include -#include -#include - -/* Application-specific. */ - -#define STR(x) vstring_str(x) -#define LEN(x) VSTRING_LEN(x) - -#define UCHAR(x) ((unsigned char *) (x)) - -static VSTRING *escape(VSTRING *escaped, char *input, int len) -{ - char *cp; - unsigned ch; - - VSTRING_RESET(escaped); - for (cp = input; cp < input + len; cp++) { - ch = *UCHAR(cp); - if (ISASCII(ch) && ISPRINT(ch)) - VSTRING_ADDCH(escaped, ch); - else - vstring_sprintf_append(escaped, "\\%03o", ch); - } - VSTRING_TERMINATE(escaped); - return (escaped); -} - -int main(int unused_argc, char **argv) -{ - VSTRING *input = vstring_alloc(100); - VSTRING *escaped = vstring_alloc(100); - VSTRING *result = vstring_alloc(100); - int len; - - msg_vstream_init(argv[0], VSTREAM_ERR); - - while (vstring_get_nonl(input, VSTREAM_IN) != VSTREAM_EOF) { - VSTRING_SPACE(result, LEN(input)); - if (sasl_decode64(STR(input), LEN(input), - STR(result), &len) != SASL_OK) - msg_fatal("malformed input"); - vstream_printf("%s\n", STR(escape(escaped, STR(result), len))); - vstream_fflush(VSTREAM_OUT); - } - return (0); -} diff --git a/postfix/src/base64/base64encode.c b/postfix/src/base64/base64encode.c deleted file mode 100644 index 73ee0dc11..000000000 --- a/postfix/src/base64/base64encode.c +++ /dev/null @@ -1,77 +0,0 @@ -/* base64encode - transform printable form to base 64 data */ - -/* System library. */ - -#include -#include - -/* SASL library. */ - -#include -#include - -/* Utility library. */ - -#include -#include -#include -#include -#include - -/* Application-specific. */ - -#define STR(x) vstring_str(x) -#define LEN(x) VSTRING_LEN(x) - -#define UCHAR(x) ((unsigned char *) (x)) - -static VSTRING *unescape(VSTRING *unescaped, VSTRING *input) -{ - char *cp = STR(input); - int ch; - int oval; - int i; - - VSTRING_RESET(unescaped); - while ((ch = *UCHAR(cp++)) != 0) { - switch (ch) { - case '\\': - for (oval = 0, i = 0; i < 3 && (ch = *UCHAR(cp)) != 0; i++) { - if (!ISDIGIT(ch) || ch == '8' || ch == '9') - break; - oval = (oval << 3) | (ch - '0'); - cp++; - } - VSTRING_ADDCH(unescaped, oval); - break; - default: - VSTRING_ADDCH(unescaped, ch); - break; - } - } - VSTRING_TERMINATE(unescaped); - return (unescaped); -} - -int main(int unused_argc, char **argv) -{ - VSTRING *input = vstring_alloc(100); - VSTRING *unescaped = vstring_alloc(100); - VSTRING *result = vstring_alloc(100); - int result_len; - int len; - - msg_vstream_init(argv[0], VSTREAM_ERR); - - while (vstring_get_nonl(input, VSTREAM_IN) != VSTREAM_EOF) { - unescape(unescaped, input); - result_len = ((LEN(unescaped) + 2) / 3) * 4 + 1; - VSTRING_SPACE(result, result_len); - if (sasl_encode64(STR(unescaped), LEN(unescaped), STR(result), - result_len, &len) != SASL_OK) - msg_panic("sasl_encode64 botch"); - vstream_printf("%.*s\n", len, STR(result)); - vstream_fflush(VSTREAM_OUT); - } - return (0); -} diff --git a/postfix/src/bounce/bounce_notify_util.c b/postfix/src/bounce/bounce_notify_util.c index b31a1e8f5..cc5e15f6b 100644 --- a/postfix/src/bounce/bounce_notify_util.c +++ b/postfix/src/bounce/bounce_notify_util.c @@ -339,10 +339,10 @@ int bounce_boilerplate(VSTREAM *bounce, BOUNCE_INFO *bounce_info) "####################################################################"); post_mail_fputs(bounce, ""); post_mail_fprintf(bounce, - "Your message could not be delivered for %.1g hours.", + "Your message could not be delivered for %.1f hours.", var_delay_warn_time / 3600.0); post_mail_fprintf(bounce, - "It will be retried until it is %.1g days old.", + "It will be retried until it is %.1f days old.", var_max_queue_time / 86400.0); } diff --git a/postfix/src/global/Makefile.in b/postfix/src/global/Makefile.in index fac2db938..a9a5fffd9 100644 --- a/postfix/src/global/Makefile.in +++ b/postfix/src/global/Makefile.in @@ -428,13 +428,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 diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 8ff8a2a19..93a5bf9cd 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -237,6 +237,14 @@ extern char *var_rcpt_witheld; #define DEF_STRICT_RFC821_ENV 0 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 DEF_BROKEN_AUTH_CLNTS 0 +extern bool var_broken_auth_clients; + /* * Standards violation: disable VRFY. */ @@ -712,7 +720,7 @@ extern int var_smtpd_err_sleep; extern int var_smtpd_junk_cmd_limit; /* - * SASL authentication support, server side. + * SASL authentication support, SMTP server side. */ #define VAR_SMTPD_SASL_ENABLE "smtpd_sasl_auth_enable" #define DEF_SMTPD_SASL_ENABLE 0 @@ -727,7 +735,7 @@ extern char *var_smtpd_sasl_opts; extern char *var_smtpd_sasl_realm; /* - * SASL authentication support, client side. + * SASL authentication support, SMTP client side. */ #define VAR_SMTP_SASL_ENABLE "smtp_sasl_auth_enable" #define DEF_SMTP_SASL_ENABLE 0 @@ -741,6 +749,24 @@ extern char *var_smtp_sasl_passwd; #define DEF_SMTP_SASL_OPTS "noplaintext, noanonymous" extern char *var_smtp_sasl_opts; + /* + * SASL authentication support, LMTP client side. + */ +#define VAR_LMTP_SASL_ENABLE "lmtp_sasl_auth_enable" +#define DEF_LMTP_SASL_ENABLE 0 +extern bool var_lmtp_sasl_enable; + +#define VAR_LMTP_SASL_PASSWD "lmtp_sasl_password_maps" +#define DEF_LMTP_SASL_PASSWD "" +extern char *var_lmtp_sasl_passwd; + +#define VAR_LMTP_SASL_OPTS "lmtp_sasl_security_options" +#define DEF_LMTP_SASL_OPTS "noplaintext, noanonymous" +extern char *var_lmtp_sasl_opts; + + /* + * SASL-based relay etc. control. + */ #define PERMIT_SASL_AUTH "permit_sasl_authenticated" /* @@ -862,7 +888,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 5 +#define DEF_FLOCK_TRIES 10 extern int var_flock_tries; #define VAR_FLOCK_DELAY "deliver_lock_delay" @@ -1110,18 +1136,23 @@ extern char *var_export_environ; #define VAR_VIRT_MAILBOX_MAPS "virtual_mailbox_maps" #define DEF_VIRT_MAILBOX_MAPS "" extern char *var_mailbox_maps; + #define VAR_VIRT_UID_MAPS "virtual_uid_maps" #define DEF_VIRT_UID_MAPS "" extern char *var_uid_maps; + #define VAR_VIRT_GID_MAPS "virtual_gid_maps" #define DEF_VIRT_GID_MAPS "" extern char *var_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 -extern int var_virt_minimum_uid; +extern int var_virt_minimum_uid; + #define VAR_VIRT_MAILBOX_BASE "virtual_mailbox_base" #define DEF_VIRT_MAILBOX_BASE "" extern char *var_virt_mailbox_base; diff --git a/postfix/src/global/mail_queue.c b/postfix/src/global/mail_queue.c index 23e18cccc..bb83f566d 100644 --- a/postfix/src/global/mail_queue.c +++ b/postfix/src/global/mail_queue.c @@ -415,7 +415,8 @@ VSTREAM *mail_queue_open(const char *queue_name, const char *queue_id, * missing subdirectory. */ if ((fp = vstream_fopen(path, flags, mode)) == 0) - if ((flags & O_CREAT) == O_CREAT && mail_queue_mkdirs(path) == 0) - fp = vstream_fopen(path, flags, mode); + if (errno == ENOENT) + if ((flags & O_CREAT) == O_CREAT && mail_queue_mkdirs(path) == 0) + fp = vstream_fopen(path, flags, mode); return (fp); } diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 0b70e3714..c69c7e47a 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -15,7 +15,7 @@ * Version of this program. */ #define VAR_MAIL_VERSION "mail_version" -#define DEF_MAIL_VERSION "Snapshot-20010105" +#define DEF_MAIL_VERSION "Snapshot-20010122" extern char *var_mail_version; /* LICENSE diff --git a/postfix/src/lmtp/Makefile.in b/postfix/src/lmtp/Makefile.in index 7c8f4db72..9821cf6af 100644 --- a/postfix/src/lmtp/Makefile.in +++ b/postfix/src/lmtp/Makefile.in @@ -1,8 +1,10 @@ SHELL = /bin/sh SRCS = lmtp.c lmtp_connect.c lmtp_proto.c lmtp_chat.c lmtp_session.c \ - lmtp_addr.c lmtp_trouble.c lmtp_state.c + lmtp_addr.c lmtp_trouble.c lmtp_state.c lmtp_sasl_glue.c \ + lmtp_sasl_proto.c OBJS = lmtp.o lmtp_connect.o lmtp_proto.o lmtp_chat.o lmtp_session.o \ - lmtp_addr.o lmtp_trouble.o lmtp_state.o + lmtp_addr.o lmtp_trouble.o lmtp_state.o lmtp_sasl_glue.o \ + lmtp_sasl_proto.o HDRS = lmtp.h TESTSRC = WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \ @@ -79,6 +81,7 @@ lmtp.o: ../../include/debug_peer.h lmtp.o: ../../include/mail_error.h lmtp.o: ../../include/mail_server.h lmtp.o: lmtp.h +lmtp.o: lmtp_sasl.h lmtp_addr.o: lmtp_addr.c lmtp_addr.o: ../../include/sys_defs.h lmtp_addr.o: ../../include/msg.h @@ -113,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 @@ -155,9 +160,42 @@ 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: ../../include/quote_821_local.h +lmtp_proto.o: lmtp_sasl.h +lmtp_sasl_glue.o: lmtp_sasl_glue.c +lmtp_sasl_glue.o: ../../include/sys_defs.h +lmtp_sasl_glue.o: ../../include/msg.h +lmtp_sasl_glue.o: ../../include/mymalloc.h +lmtp_sasl_glue.o: ../../include/stringops.h +lmtp_sasl_glue.o: ../../include/vstring.h +lmtp_sasl_glue.o: ../../include/vbuf.h +lmtp_sasl_glue.o: ../../include/split_at.h +lmtp_sasl_glue.o: ../../include/name_mask.h +lmtp_sasl_glue.o: ../../include/mail_params.h +lmtp_sasl_glue.o: ../../include/string_list.h +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 lmtp_session.o: ../../include/mymalloc.h @@ -176,12 +214,12 @@ 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 lmtp_state.o: ../../include/deliver_request.h lmtp_state.o: ../../include/recipient_list.h +lmtp_state.o: lmtp_sasl.h lmtp_trouble.o: lmtp_trouble.c lmtp_trouble.o: ../../include/sys_defs.h lmtp_trouble.o: ../../include/msg.h diff --git a/postfix/src/lmtp/lmtp.c b/postfix/src/lmtp/lmtp.c index dfd3ec5c3..ec0e1c73c 100644 --- a/postfix/src/lmtp/lmtp.c +++ b/postfix/src/lmtp/lmtp.c @@ -49,6 +49,7 @@ /* RFC 1870 (Message Size Declaration) /* RFC 2033 (LMTP protocol) /* RFC 2197 (Pipelining) +/* RFC 2554 (AUTH command) /* DIAGNOSTICS /* Problems and transactions are logged to \fBsyslogd\fR(8). /* Corrupted message files are marked so that the queue manager can @@ -85,6 +86,27 @@ /* .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 @@ -231,6 +253,7 @@ /* Application-specific. */ #include "lmtp.h" +#include "lmtp_sasl.h" /* * Tunable parameters. These have compiled-in defaults that can be overruled @@ -252,6 +275,9 @@ int var_lmtp_cache_conn; int var_lmtp_skip_quit_resp; char *var_notify_classes; char *var_error_rcpt; +char *var_lmtp_sasl_opts; +char *var_lmtp_sasl_passwd; +bool var_lmtp_sasl_enable; /* * Global variables. @@ -432,6 +458,10 @@ 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) + lmtp_sasl_initialize(); +#endif } /* cleanup - close any open connections, etc. */ @@ -446,6 +476,10 @@ static void cleanup(void) msg_info("cleanup: just closed down session"); } lmtp_state_free(state); +#ifdef USE_SASL_AUTH + if (var_lmtp_sasl_enable) + sasl_done(); +#endif } /* pre_accept - see if tables have changed */ @@ -467,6 +501,8 @@ int main(int argc, char **argv) VAR_DEBUG_PEER_LIST, DEF_DEBUG_PEER_LIST, &var_debug_peer_list, 0, 0, VAR_NOTIFY_CLASSES, DEF_NOTIFY_CLASSES, &var_notify_classes, 0, 0, VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0, + VAR_LMTP_SASL_PASSWD, DEF_LMTP_SASL_PASSWD, &var_lmtp_sasl_passwd, 0, 0, + VAR_LMTP_SASL_OPTS, DEF_LMTP_SASL_OPTS, &var_lmtp_sasl_opts, 0, 0, 0, }; static CONFIG_INT_TABLE int_table[] = { diff --git a/postfix/src/lmtp/lmtp.h b/postfix/src/lmtp/lmtp.h index 0f53c46a7..9574b648a 100644 --- a/postfix/src/lmtp/lmtp.h +++ b/postfix/src/lmtp/lmtp.h @@ -8,6 +8,14 @@ /* DESCRIPTION /* .nf + /* + * SASL library. + */ +#ifdef USE_SASL_AUTH +#include +#include +#endif + /* * Utility library. */ @@ -35,6 +43,15 @@ typedef struct LMTP_STATE { int features; /* server features */ ARGV *history; /* transaction log */ int error_mask; /* error classes */ +#ifdef USE_SASL_AUTH + char *sasl_mechanism_list; /* server mechanism list */ + char *sasl_username; /* client username */ + char *sasl_passwd; /* client password */ + sasl_conn_t *sasl_conn; /* SASL internal state */ + VSTRING *sasl_encoded; /* encoding buffer */ + VSTRING *sasl_decoded; /* decoding buffer */ + sasl_callback_t *sasl_callbacks; /* stateful callbacks */ +#endif int sndbufsize; /* total window size */ int sndbuffree; /* remaining window */ int reuse; /* connection being reused */ @@ -44,6 +61,7 @@ typedef struct LMTP_STATE { #define LMTP_FEATURE_8BITMIME (1<<1) #define LMTP_FEATURE_PIPELINING (1<<2) #define LMTP_FEATURE_SIZE (1<<3) +#define SMTP_FEATURE_AUTH (1<<5) /* * lmtp.c diff --git a/postfix/src/lmtp/lmtp_chat.c b/postfix/src/lmtp/lmtp_chat.c index 9fd23f2bf..19b37cc03 100644 --- a/postfix/src/lmtp/lmtp_chat.c +++ b/postfix/src/lmtp/lmtp_chat.c @@ -104,6 +104,7 @@ #include #include #include +#include /* Application-specific. */ @@ -172,7 +173,6 @@ LMTP_RESP *lmtp_chat_resp(LMTP_STATE *state) { LMTP_SESSION *session = state->session; static LMTP_RESP rdata; - int more; char *cp; int last_char; @@ -190,17 +190,12 @@ LMTP_RESP *lmtp_chat_resp(LMTP_STATE *state) VSTRING_RESET(rdata.buf); for (;;) { last_char = smtp_get(state->buffer, session->stream, var_line_limit); - cp = printable(STR(state->buffer), '?'); + printable(STR(state->buffer), '?'); if (last_char != '\n') msg_warn("%s: response longer than %d: %.30s...", - session->namaddr, var_line_limit, cp); + session->namaddr, var_line_limit, STR(state->buffer)); if (msg_verbose) - msg_info("< %s: %s", session->namaddr, cp); - while (ISDIGIT(*cp)) - cp++; - rdata.code = (cp - STR(state->buffer) == 3 ? - atoi(STR(state->buffer)) : 0); - more = (*cp == '-'); + msg_info("< %s: %s", session->namaddr, STR(state->buffer)); /* * Defend against a denial of service attack by limiting the amount @@ -212,13 +207,23 @@ LMTP_RESP *lmtp_chat_resp(LMTP_STATE *state) vstring_strcat(rdata.buf, STR(state->buffer)); lmtp_chat_append(state, "In: ", STR(state->buffer)); } - if (VSTRING_LEN(state->buffer) == 0) /* XXX remote brain damage */ - continue; - if (!ISDIGIT(STR(state->buffer)[0])) /* XXX remote brain damage */ - continue; - if (more == 0) - break; + + /* + * Parse into code and text. Ignore unrecognized garbage. This means + * that any character except space (or end of line) will have the + * same effect as the '-' line continuation character. + */ + for (cp = STR(state->buffer); *cp && ISDIGIT(*cp); cp++) + /* void */ ; + if (cp - STR(state->buffer) == 3) { + if (*cp == '-') + continue; + if (*cp == ' ' || *cp == 0) + break; + } + state->error_mask |= MAIL_ERROR_PROTOCOL; } + rdata.code = atoi(STR(state->buffer)); VSTRING_TERMINATE(rdata.buf); rdata.str = STR(rdata.buf); return (&rdata); diff --git a/postfix/src/lmtp/lmtp_proto.c b/postfix/src/lmtp/lmtp_proto.c index 93ed07dd0..cd34d7556 100644 --- a/postfix/src/lmtp/lmtp_proto.c +++ b/postfix/src/lmtp/lmtp_proto.c @@ -116,11 +116,12 @@ #include #include #include +#include /* Application-specific. */ #include "lmtp.h" -#include "quote_821_local.h" +#include "lmtp_sasl.h" /* * Sender and receiver state. A session does not necessarily go through a @@ -193,7 +194,7 @@ int lmtp_lhlo(LMTP_STATE *state) */ if (((resp = lmtp_chat_resp(state))->code / 100) != 2) return (lmtp_site_fail(state, resp->code, - "%s refused to talk to me: %s", + "host %s refused to talk to me: %s", session->namaddr, translit(resp->str, "\n", " "))); /* @@ -202,7 +203,7 @@ int lmtp_lhlo(LMTP_STATE *state) lmtp_chat_cmd(state, "LHLO %s", var_myhostname); if ((resp = lmtp_chat_resp(state))->code / 100 != 2) return (lmtp_site_fail(state, resp->code, - "%s refused to talk to me: %s", + "host %s refused to talk to me: %s", session->namaddr, translit(resp->str, "\n", " "))); @@ -223,11 +224,20 @@ int lmtp_lhlo(LMTP_STATE *state) state->features |= LMTP_FEATURE_PIPELINING; else if (strcasecmp(word, "SIZE") == 0) state->features |= LMTP_FEATURE_SIZE; +#ifdef USE_SASL_AUTH + else if (var_lmtp_sasl_enable && strcasecmp(word, "AUTH") == 0) + lmtp_sasl_helo_auth(state, words); +#endif } } if (msg_verbose) msg_info("server features: 0x%x", state->features); +#ifdef USE_SASL_AUTH + if (var_lmtp_sasl_enable && (state->features & SMTP_FEATURE_AUTH)) + return (lmtp_sasl_helo_login(state)); +#endif + /* * We use LMTP command pipelining if the server said it supported it. * Since we use blocking I/O, RFC 2197 says that we should inspect the @@ -463,7 +473,7 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state) case LMTP_STATE_MAIL: if (resp->code / 100 != 2) { lmtp_mesg_fail(state, resp->code, - "%s said: %s", session->namaddr, + "host %s said: %s", session->namaddr, translit(resp->str, "\n", " ")); mail_from_rejected = 1; } @@ -487,7 +497,7 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state) survivors[nrcpt++] = recv_rcpt; } else { lmtp_rcpt_fail(state, resp->code, rcpt, - "%s said: %s", session->namaddr, + "host %s said: %s", session->namaddr, translit(resp->str, "\n", " ")); rcpt->offset = 0; /* in case deferred */ } @@ -505,7 +515,7 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state) if (resp->code / 100 != 3) { if (nrcpt > 0) lmtp_mesg_fail(state, resp->code, - "%s said: %s", session->namaddr, + "host %s said: %s", session->namaddr, translit(resp->str, "\n", " ")); nrcpt = -1; } @@ -535,7 +545,7 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state) } } else { lmtp_rcpt_fail(state, resp->code, rcpt, - "%s said: %s", session->namaddr, + "host %s said: %s", session->namaddr, translit(resp->str, "\n", " ")); rcpt->offset = 0; /* in case deferred */ } diff --git a/postfix/src/lmtp/lmtp_sasl.h b/postfix/src/lmtp/lmtp_sasl.h new file mode 100644 index 000000000..1054d688c --- /dev/null +++ b/postfix/src/lmtp/lmtp_sasl.h @@ -0,0 +1,39 @@ +/*++ +/* NAME +/* lmtp_sasl 3h +/* SUMMARY +/* Postfix SASL interface for LMTP client +/* SYNOPSIS +/* #include "lmtp_sasl.h" +/* DESCRIPTION +/* .nf + + /* + * SASL protocol functions + */ +extern void lmtp_sasl_initialize(void); +extern void lmtp_sasl_connect(LMTP_STATE *); +extern int lmtp_sasl_passwd_lookup(LMTP_STATE *); +extern void lmtp_sasl_start(LMTP_STATE *); +extern int lmtp_sasl_authenticate(LMTP_STATE *, VSTRING *); +extern void lmtp_sasl_cleanup(LMTP_STATE *); + +extern void lmtp_sasl_helo_auth(LMTP_STATE *, const char *); +extern int lmtp_sasl_helo_login(LMTP_STATE *); + +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Initial implementation by: +/* Till Franke +/* SuSE Rhein/Main AG +/* 65760 Eschborn, Germany +/* +/* Adopted by: +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ diff --git a/postfix/src/lmtp/lmtp_sasl_glue.c b/postfix/src/lmtp/lmtp_sasl_glue.c new file mode 100644 index 000000000..ba57156a7 --- /dev/null +++ b/postfix/src/lmtp/lmtp_sasl_glue.c @@ -0,0 +1,512 @@ +/*++ +/* NAME +/* lmtp_sasl 3 +/* SUMMARY +/* Postfix SASL interface for LMTP client +/* SYNOPSIS +/* #include lmtp_sasl.h +/* +/* void lmtp_sasl_initialize() +/* +/* void lmtp_sasl_connect(state) +/* LMTP_STATE *state; +/* +/* void lmtp_sasl_start(state) +/* LMTP_STATE *state; +/* +/* int lmtp_sasl_passwd_lookup(state) +/* LMTP_STATE *state; +/* +/* int lmtp_sasl_authenticate(state, why) +/* LMTP_STATE *state; +/* VSTRING *why; +/* +/* void lmtp_sasl_cleanup(state) +/* LMTP_STATE *state; +/* DESCRIPTION +/* lmtp_sasl_initialize() initializes the SASL library. This +/* routine must be called once at process startup, before any +/* chroot operations. +/* +/* lmtp_sasl_connect() performs per-session initialization. This +/* routine must be called once at the start of each connection. +/* +/* lmtp_sasl_start() performs per-session initialization. This +/* routine must be called once per session before doing any SASL +/* authentication. +/* +/* lmtp_sasl_passwd_lookup() looks up the username/password +/* for the current SMTP server. The result is zero in case +/* of failure. +/* +/* lmtp_sasl_authenticate() implements the SASL authentication +/* dialog. The result is < 0 in case of protocol failure, zero in +/* case of unsuccessful authentication, > 0 in case of success. +/* The why argument is updated with a reason for failure. +/* This routine must be called only when lmtp_sasl_passwd_lookup() +/* suceeds. +/* +/* lmtp_sasl_cleanup() cleans up. It must be called at the +/* end of every SMTP session that uses SASL authentication. +/* This routine is a noop for non-SASL sessions. +/* +/* Arguments: +/* .IP state +/* Session context. +/* .IP mech_list +/* String of SASL mechanisms (separated by blanks) +/* DIAGNOSTICS +/* All errors are fatal. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Original author: +/* Till Franke +/* SuSE Rhein/Main AG +/* 65760 Eschborn, Germany +/* +/* Adopted by: +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + + /* + * System library. + */ +#include +#include +#include +#ifdef STRCASECMP_IN_STRINGS_H +#include +#endif + + /* + * Utility library + */ +#include +#include +#include +#include +#include + + /* + * Global library + */ +#include +#include +#include + + /* + * Application-specific + */ +#include "lmtp.h" +#include "lmtp_sasl.h" + +#ifdef USE_SASL_AUTH + + /* + * Authentication security options. + */ +static NAME_MASK lmtp_sasl_sec_mask[] = { + "noplaintext", SASL_SEC_NOPLAINTEXT, + "noactive", SASL_SEC_NOACTIVE, + "nodictionary", SASL_SEC_NODICTIONARY, + "noanonymous", SASL_SEC_NOANONYMOUS, + 0, +}; + +static int lmtp_sasl_sec_opts; + + /* + * Silly little macros. + */ +#define STR(x) vstring_str(x) + + /* + * Per-host login/password information. + */ +static MAPS *lmtp_sasl_passwd_map; + +/* lmtp_sasl_log - logging call-back routine */ + +static int lmtp_sasl_log(void *unused_context, int priority, + const char *message) +{ + switch (priority) { + case SASL_LOG_ERR: + case SASL_LOG_WARNING: + msg_warn("%s", message); + break; + case SASL_LOG_INFO: + if (msg_verbose) + msg_info("%s", message); + break; + } + return (SASL_OK); +} + +/* lmtp_sasl_get_user - username lookup call-back routine */ + +static int lmtp_sasl_get_user(void *context, int unused_id, const char **result, + unsigned *len) +{ + char *myname = "lmtp_sasl_get_user"; + LMTP_STATE *state = (LMTP_STATE *) context; + + if (msg_verbose) + msg_info("%s: %s", myname, state->sasl_username); + + /* + * Sanity check. + */ + if (state->sasl_passwd == 0) + msg_panic("%s: no username looked up", myname); + + *result = state->sasl_username; + if (len) + *len = strlen(state->sasl_username); + return (SASL_OK); +} + +/* lmtp_sasl_get_passwd - password lookup call-back routine */ + +static int lmtp_sasl_get_passwd(sasl_conn_t *conn, void *context, + int id, sasl_secret_t **psecret) +{ + char *myname = "lmtp_sasl_get_passwd"; + LMTP_STATE *state = (LMTP_STATE *) context; + int len; + + if (msg_verbose) + msg_info("%s: %s", myname, state->sasl_passwd); + + /* + * Sanity check. + */ + if (!conn || !psecret || id != SASL_CB_PASS) + return (SASL_BADPARAM); + if (state->sasl_passwd == 0) + msg_panic("%s: no password looked up", myname); + + /* + * Convert the password into a counted string. + */ + len = strlen(state->sasl_passwd); + if ((*psecret = (sasl_secret_t *) malloc(sizeof(sasl_secret_t) + len)) == 0) + return (SASL_NOMEM); + (*psecret)->len = len; + memcpy((*psecret)->data, state->sasl_passwd, len + 1); + + return (SASL_OK); +} + +/* lmtp_sasl_passwd_lookup - password lookup routine */ + +int lmtp_sasl_passwd_lookup(LMTP_STATE *state) +{ + char *myname = "lmtp_sasl_passwd_lookup"; + const char *value; + char *passwd; + + /* + * Sanity check. + */ + if (lmtp_sasl_passwd_map == 0) + msg_panic("%s: passwd map not initialized", myname); + + /* + * Look up the per-server password information. Try the hostname first, + * then try the destination. + */ + if ((value = maps_find(lmtp_sasl_passwd_map, state->session->host, 0)) != 0 + || (value = maps_find(lmtp_sasl_passwd_map, state->request->nexthop, 0)) != 0) { + state->sasl_username = mystrdup(value); + passwd = split_at(state->sasl_username, ':'); + state->sasl_passwd = mystrdup(passwd ? passwd : ""); + if (msg_verbose) + msg_info("%s: host `%s' user `%s' pass `%s'", + myname, state->session->host, + state->sasl_username, state->sasl_passwd); + return (1); + } else { + if (msg_verbose) + msg_info("%s: host `%s' no auth info found", + myname, state->session->host); + return (0); + } +} + +/* lmtp_sasl_initialize - per-process initialization (pre jail) */ + +void lmtp_sasl_initialize(void) +{ + + /* + * Global callbacks. These have no per-session context. + */ + static sasl_callback_t callbacks[] = { + {SASL_CB_LOG, &lmtp_sasl_log, 0}, + {SASL_CB_LIST_END, 0, 0} + }; + + /* + * Sanity check. + */ + if (lmtp_sasl_passwd_map) + msg_panic("lmtp_sasl_initialize: repeated call"); + if (*var_lmtp_sasl_passwd == 0) + msg_fatal("specify a password table via the `%s' configuration parameter", + VAR_LMTP_SASL_PASSWD); + + /* + * Open the per-host password table and initialize the SASL library. Use + * shared locks for reading, just in case someone updates the table. + */ + lmtp_sasl_passwd_map = maps_create("lmtp_sasl_passwd", + var_lmtp_sasl_passwd, DICT_FLAG_LOCK); + if (sasl_client_init(callbacks) != SASL_OK) + msg_fatal("SASL library initialization"); + + /* + * Configuration parameters. + */ + lmtp_sasl_sec_opts = name_mask(VAR_LMTP_SASL_OPTS, lmtp_sasl_sec_mask, + var_lmtp_sasl_opts); +} + +/* lmtp_sasl_connect - per-session client initialization */ + +void lmtp_sasl_connect(LMTP_STATE *state) +{ + state->sasl_mechanism_list = 0; + state->sasl_username = 0; + state->sasl_passwd = 0; + state->sasl_conn = 0; + state->sasl_encoded = 0; + state->sasl_decoded = 0; + state->sasl_callbacks = 0; +} + +/* lmtp_sasl_start - per-session SASL initialization */ + +void lmtp_sasl_start(LMTP_STATE *state) +{ + static sasl_callback_t callbacks[] = { + {SASL_CB_USER, &lmtp_sasl_get_user, 0}, + {SASL_CB_AUTHNAME, &lmtp_sasl_get_user, 0}, + {SASL_CB_PASS, &lmtp_sasl_get_passwd, 0}, + {SASL_CB_LIST_END, 0, 0} + }; + sasl_callback_t *cp; + sasl_security_properties_t sec_props; + + if (msg_verbose) + msg_info("starting new SASL client"); + + /* + * Per-session initialization. Provide each session with its own callback + * context. + */ +#define NULL_SECFLAGS 0 + + state->sasl_callbacks = (sasl_callback_t *) mymalloc(sizeof(callbacks)); + memcpy((char *) state->sasl_callbacks, callbacks, sizeof(callbacks)); + for (cp = state->sasl_callbacks; cp->id != SASL_CB_LIST_END; cp++) + cp->context = (void *) state; + if (sasl_client_new("smtp", state->session->host, + state->sasl_callbacks, NULL_SECFLAGS, + (sasl_conn_t **) &state->sasl_conn) != SASL_OK) + msg_fatal("per-session SASL client initialization"); + + /* + * Per-session security properties. XXX This routine is not sufficiently + * documented. What is the purpose of all this? + */ + memset(&sec_props, 0L, sizeof(sec_props)); + sec_props.min_ssf = 0; + sec_props.max_ssf = 1; /* don't allow real SASL + * security layer */ + sec_props.security_flags = lmtp_sasl_sec_opts; + sec_props.maxbufsize = 0; + sec_props.property_names = 0; + sec_props.property_values = 0; + if (sasl_setprop(state->sasl_conn, SASL_SEC_PROPS, + &sec_props) != SASL_OK) + msg_fatal("set per-session SASL security properties"); + + /* + * We use long-lived conversion buffers rather than local variables in + * order to avoid memory leaks in case of read/write timeout or I/O + * error. + */ + state->sasl_encoded = vstring_alloc(10); + state->sasl_decoded = vstring_alloc(10); +} + +/* lmtp_sasl_authenticate - run authentication protocol */ + +int lmtp_sasl_authenticate(LMTP_STATE *state, VSTRING *why) +{ + char *myname = "lmtp_sasl_authenticate"; + unsigned enc_length; + unsigned enc_length_out; + char *clientout; + unsigned clientoutlen; + unsigned serverinlen; + LMTP_RESP *resp; + const char *mechanism; + int result; + char *line; + +#define NO_SASL_SECRET 0 +#define NO_SASL_INTERACTION 0 +#define NO_SASL_LANGLIST ((const char *) 0) +#define NO_SASL_OUTLANG ((const char **) 0) + + if (msg_verbose) + msg_info("%s: %s: SASL mechanisms %s", + myname, state->session->namaddr, state->sasl_mechanism_list); + + /* + * Start the client side authentication protocol. + */ + result = sasl_client_start((sasl_conn_t *) state->sasl_conn, + state->sasl_mechanism_list, + NO_SASL_SECRET, NO_SASL_INTERACTION, + &clientout, &clientoutlen, &mechanism); + if (result != SASL_OK && result != SASL_CONTINUE) { + vstring_sprintf(why, "cannot SASL authenticate to server %s: %s", + state->session->namaddr, + sasl_errstring(result, NO_SASL_LANGLIST, + NO_SASL_OUTLANG)); + return (-1); + } + + /* + * Send the AUTH command and the optional initial client response. + * sasl_encode64() produces four bytes for each complete or incomplete + * triple of input bytes. Allocate an extra byte for string termination. + */ +#define ENCODE64_LENGTH(n) ((((n) + 2) / 3) * 4) + + if (clientoutlen > 0) { + if (msg_verbose) + msg_info("%s: %s: uncoded initial reply: %.*s", + myname, state->session->namaddr, + (int) clientoutlen, clientout); + enc_length = ENCODE64_LENGTH(clientoutlen) + 1; + VSTRING_SPACE(state->sasl_encoded, enc_length); + if (sasl_encode64(clientout, clientoutlen, + STR(state->sasl_encoded), enc_length, + &enc_length_out) != SASL_OK) + msg_panic("%s: sasl_encode64 botch", myname); + free(clientout); + lmtp_chat_cmd(state, "AUTH %s %s", mechanism, STR(state->sasl_encoded)); + } else { + lmtp_chat_cmd(state, "AUTH %s", mechanism); + } + + /* + * Step through the authentication protocol until the server tells us + * that we are done. + */ + while ((resp = lmtp_chat_resp(state))->code / 100 == 3) { + + /* + * Process a server challenge. + */ + line = resp->str; + (void) mystrtok(&line, "- \t\n"); /* skip over result code */ + serverinlen = strlen(line); + VSTRING_SPACE(state->sasl_decoded, serverinlen); + if (sasl_decode64(line, serverinlen, + STR(state->sasl_decoded), &enc_length) != SASL_OK) { + vstring_sprintf(why, "malformed SASL challenge from server %s", + state->session->namaddr); + return (-1); + } + if (msg_verbose) + msg_info("%s: %s: decoded challenge: %.*s", + myname, state->session->namaddr, + (int) enc_length, STR(state->sasl_decoded)); + result = sasl_client_step((sasl_conn_t *) state->sasl_conn, + STR(state->sasl_decoded), enc_length, + NO_SASL_INTERACTION, &clientout, &clientoutlen); + if (result != SASL_OK && result != SASL_CONTINUE) + msg_warn("SASL authentication failed to server %s: %s", + state->session->namaddr, + sasl_errstring(result, NO_SASL_LANGLIST, + NO_SASL_OUTLANG)); + + /* + * Send a client response. + */ + if (clientoutlen > 0) { + if (msg_verbose) + msg_info("%s: %s: uncoded client response %.*s", + myname, state->session->namaddr, + (int) clientoutlen, clientout); + enc_length = ENCODE64_LENGTH(clientoutlen) + 1; + VSTRING_SPACE(state->sasl_encoded, enc_length); + if (sasl_encode64(clientout, clientoutlen, + STR(state->sasl_encoded), enc_length, + &enc_length_out) != SASL_OK) + msg_panic("%s: sasl_encode64 botch", myname); + free(clientout); + } else { + vstring_strcat(state->sasl_encoded, ""); + } + lmtp_chat_cmd(state, "%s", STR(state->sasl_encoded)); + } + + /* + * We completed the authentication protocol. + */ + if (resp->code / 100 != 2) { + vstring_sprintf(why, "SASL authentication failed; server %s said: %s", + state->session->namaddr, resp->str); + return (0); + } + return (1); +} + +/* lmtp_sasl_cleanup - per-session cleanup */ + +void lmtp_sasl_cleanup(LMTP_STATE *state) +{ + if (state->sasl_username) { + myfree(state->sasl_username); + state->sasl_username = 0; + } + if (state->sasl_passwd) { + myfree(state->sasl_passwd); + state->sasl_passwd = 0; + } + if (state->sasl_mechanism_list) { + myfree(state->sasl_mechanism_list); /* allocated in lmtp_helo */ + state->sasl_mechanism_list = 0; + } + if (state->sasl_conn) { + if (msg_verbose) + msg_info("disposing SASL state information"); + sasl_dispose(&state->sasl_conn); + } + if (state->sasl_callbacks) { + myfree((char *) state->sasl_callbacks); + state->sasl_callbacks = 0; + } + if (state->sasl_encoded) { + vstring_free(state->sasl_encoded); + state->sasl_encoded = 0; + } + if (state->sasl_decoded) { + vstring_free(state->sasl_decoded); + state->sasl_decoded = 0; + } +} + +#endif diff --git a/postfix/src/lmtp/lmtp_sasl_proto.c b/postfix/src/lmtp/lmtp_sasl_proto.c new file mode 100644 index 000000000..8eaeafd14 --- /dev/null +++ b/postfix/src/lmtp/lmtp_sasl_proto.c @@ -0,0 +1,120 @@ +/*++ +/* NAME +/* lmtp_sasl_proto 3 +/* SUMMARY +/* Postfix SASL interface for LMTP client +/* SYNOPSIS +/* #include lmtp_sasl.h +/* +/* void lmtp_sasl_helo_auth(state, words) +/* LMTP_STATE *state; +/* const char *words; +/* +/* int lmtp_sasl_helo_login(state) +/* LMTP_STATE *state; +/* DESCRIPTION +/* This module contains random chunks of code that implement +/* the SMTP protocol interface for SASL negotiation. The goal +/* is to reduce clutter in the main LMTP client source code. +/* +/* lmtp_sasl_helo_auth() processes the AUTH option in the +/* SMTP server's EHLO response. +/* +/* lmtp_sasl_helo_login() authenticates the LMTP client to the +/* SMTP server, using the authentication mechanism information +/* given by the server. The result is a Postfix delivery status +/* code in case of trouble. +/* +/* Arguments: +/* .IP state +/* Session context. +/* .IP words +/* List of SASL authentication mechanisms (separated by blanks) +/* DIAGNOSTICS +/* All errors are fatal. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Original author: +/* Till Franke +/* SuSE Rhein/Main AG +/* 65760 Eschborn, Germany +/* +/* Adopted by: +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +/* System library. */ + +#include + +/* Utility library. */ + +#include +#include + +/* Global library. */ + +#include + +/* Application-specific. */ + +#include "lmtp.h" +#include "lmtp_sasl.h" + +#ifdef USE_SASL_AUTH + +/* lmtp_sasl_helo_auth - handle AUTH option in EHLO reply */ + +void lmtp_sasl_helo_auth(LMTP_STATE *state, const char *words) +{ + + /* + * XXX If the server offers a null list of authentication mechanisms, + * then pretend that the server doesn't support SASL authentication. + */ + if (state->sasl_mechanism_list) { + myfree(state->sasl_mechanism_list); + msg_warn("%s offered AUTH option multiple times", + state->session->namaddr); + state->sasl_mechanism_list = 0; + state->features &= ~SMTP_FEATURE_AUTH; + } + if (strlen(words) > 0) { + state->sasl_mechanism_list = mystrdup(words); + state->features |= SMTP_FEATURE_AUTH; + } else { + msg_warn("%s offered null AUTH mechanism list", + state->session->namaddr); + } +} + +/* lmtp_sasl_helo_login - perform SASL login */ + +int lmtp_sasl_helo_login(LMTP_STATE *state) +{ + VSTRING *why = vstring_alloc(10); + int ret = 0; + + /* + * Skip authentication when no authentication info exists for this + * server, so that we talk to each other like strangers. Otherwise, if + * authentication information exists, assume that authentication is + * required, and assume that an authentication error is recoverable. + */ + if (lmtp_sasl_passwd_lookup(state) != 0) { + lmtp_sasl_start(state); + if (lmtp_sasl_authenticate(state, why) <= 0) + ret = lmtp_site_fail(state, 450, "Authentication failed: %s", + vstring_str(why)); + } + vstring_free(why); + return (ret); +} + +#endif diff --git a/postfix/src/lmtp/lmtp_state.c b/postfix/src/lmtp/lmtp_state.c index 7a9626609..9f25f8149 100644 --- a/postfix/src/lmtp/lmtp_state.c +++ b/postfix/src/lmtp/lmtp_state.c @@ -53,11 +53,12 @@ /* Global library. */ -#include +#include /* Application-specific. */ #include "lmtp.h" +#include "lmtp_sasl.h" /* lmtp_state_alloc - initialize */ @@ -75,6 +76,9 @@ LMTP_STATE *lmtp_state_alloc(void) state->features = 0; state->history = 0; state->error_mask = 0; +#ifdef USE_SASL_AUTH + lmtp_sasl_connect(state); +#endif state->sndbufsize = 0; state->sndbuffree = 0; state->reuse = 0; @@ -88,5 +92,8 @@ void lmtp_state_free(LMTP_STATE *state) vstring_free(state->buffer); vstring_free(state->scratch); vstring_free(state->scratch2); +#ifdef USE_SASL_AUTH + lmtp_sasl_cleanup(state); +#endif myfree((char *) state); } diff --git a/postfix/src/postconf/Makefile.in b/postfix/src/postconf/Makefile.in index af5f001c1..c5d00c038 100644 --- a/postfix/src/postconf/Makefile.in +++ b/postfix/src/postconf/Makefile.in @@ -93,6 +93,7 @@ postconf.o: time_vars.h postconf.o: bool_vars.h postconf.o: int_vars.h postconf.o: str_vars.h +postconf.o: raw_vars.h postconf.o: local_vars.h postconf.o: smtp_vars.h postconf.o: time_table.h @@ -101,3 +102,4 @@ 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/postconf.c b/postfix/src/postconf/postconf.c index 80b1c2126..78d9a7f52 100644 --- a/postfix/src/postconf/postconf.c +++ b/postfix/src/postconf/postconf.c @@ -420,7 +420,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. * @@ -790,9 +790,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; diff --git a/postfix/src/smtp/Makefile.in b/postfix/src/smtp/Makefile.in index 8f97c6b58..ed46099b6 100644 --- a/postfix/src/smtp/Makefile.in +++ b/postfix/src/smtp/Makefile.in @@ -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 diff --git a/postfix/src/smtp/smtp.h b/postfix/src/smtp/smtp.h index 6643944e7..8c6dd5b06 100644 --- a/postfix/src/smtp/smtp.h +++ b/postfix/src/smtp/smtp.h @@ -85,7 +85,7 @@ extern void smtp_session_free(SMTP_SESSION *); */ extern SMTP_SESSION *smtp_connect(char *, VSTRING *); extern SMTP_SESSION *smtp_connect_host(char *, unsigned, VSTRING *); -extern SMTP_SESSION *smtp_connect_domain(char *, unsigned, VSTRING *); +extern SMTP_SESSION *smtp_connect_domain(char *, unsigned, VSTRING *, int *); /* * smtp_proto.c diff --git a/postfix/src/smtp/smtp_addr.c b/postfix/src/smtp/smtp_addr.c index 75272dde7..7c06a8e5a 100644 --- a/postfix/src/smtp/smtp_addr.c +++ b/postfix/src/smtp/smtp_addr.c @@ -6,9 +6,10 @@ /* SYNOPSIS /* #include "smtp_addr.h" /* -/* DNS_RR *smtp_domain_addr(name, why) +/* DNS_RR *smtp_domain_addr(name, why, found_myself) /* char *name; /* VSTRING *why; +/* int *found_myself; /* /* DNS_RR *smtp_host_addr(name, why) /* char *name; @@ -279,11 +280,11 @@ static int smtp_compare_mx(DNS_RR *a, DNS_RR *b) /* smtp_domain_addr - mail exchanger address lookup */ -DNS_RR *smtp_domain_addr(char *name, VSTRING *why) +DNS_RR *smtp_domain_addr(char *name, VSTRING *why, int *found_myself) { DNS_RR *mx_names; DNS_RR *addr_list = 0; - DNS_RR *self; + DNS_RR *self = 0; unsigned best_pref; unsigned best_found; @@ -363,6 +364,7 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why) /* * Clean up. */ + *found_myself = (self != 0); return (addr_list); } diff --git a/postfix/src/smtp/smtp_addr.h b/postfix/src/smtp/smtp_addr.h index d0dabba49..1e7621c9f 100644 --- a/postfix/src/smtp/smtp_addr.h +++ b/postfix/src/smtp/smtp_addr.h @@ -17,7 +17,7 @@ * Internal interfaces. */ extern DNS_RR *smtp_host_addr(char *, VSTRING *); -extern DNS_RR *smtp_domain_addr(char *, VSTRING *); +extern DNS_RR *smtp_domain_addr(char *, VSTRING *, int *); /* LICENSE /* .ad diff --git a/postfix/src/smtp/smtp_connect.c b/postfix/src/smtp/smtp_connect.c index d8017f230..6b9c58f6e 100644 --- a/postfix/src/smtp/smtp_connect.c +++ b/postfix/src/smtp/smtp_connect.c @@ -292,7 +292,8 @@ SMTP_SESSION *smtp_connect_host(char *host, unsigned port, VSTRING *why) /* smtp_connect_domain - connect to smtp server for domain */ -SMTP_SESSION *smtp_connect_domain(char *name, unsigned port, VSTRING *why) +SMTP_SESSION *smtp_connect_domain(char *name, unsigned port, VSTRING *why, + int *found_myself) { SMTP_SESSION *session = 0; DNS_RR *addr_list; @@ -306,7 +307,7 @@ SMTP_SESSION *smtp_connect_domain(char *name, unsigned port, VSTRING *why) * the primary MX host is reachable but does not want to receive our * mail, there is no point in trying the backup hosts. */ - addr_list = smtp_domain_addr(name, why); + addr_list = smtp_domain_addr(name, why, found_myself); for (addr = addr_list; addr; addr = addr->next) { if ((session = smtp_connect_addr(addr, port, why)) != 0) { session->best = (addr->pref == addr_list->pref); @@ -393,6 +394,7 @@ SMTP_SESSION *smtp_connect(char *destination, VSTRING *why) char *save; char *dest; char *cp; + int found_myself; /* * First try to deliver to the indicated destination, then try to deliver @@ -417,7 +419,7 @@ SMTP_SESSION *smtp_connect(char *destination, VSTRING *why) if (var_disable_dns || *dest == '[') { session = smtp_connect_host(host, port, why); } else { - session = smtp_connect_domain(host, port, why); + session = smtp_connect_domain(host, port, why, &found_myself); } myfree(dest_buf); @@ -426,7 +428,7 @@ SMTP_SESSION *smtp_connect(char *destination, VSTRING *why) * is the best MX relay for the destination. Agreed, an errno of OK * after failure is a weird way to reporting progress. */ - if (session != 0 || smtp_errno == SMTP_OK) + if (session != 0 || smtp_errno == SMTP_OK || found_myself) break; } diff --git a/postfix/src/smtp/smtp_proto.c b/postfix/src/smtp/smtp_proto.c index 0f4394e9d..c9b0a54e8 100644 --- a/postfix/src/smtp/smtp_proto.c +++ b/postfix/src/smtp/smtp_proto.c @@ -98,11 +98,11 @@ #include #include #include +#include /* Application-specific. */ #include "smtp.h" -#include "quote_821_local.h" #include "smtp_sasl.h" /* @@ -226,6 +226,8 @@ int smtp_helo(SMTP_STATE *state) #ifdef USE_SASL_AUTH else if (var_smtp_sasl_enable && strcasecmp(word, "AUTH") == 0) smtp_sasl_helo_auth(state, words); + else if (var_smtp_sasl_enable && strncasecmp(word, "AUTH=", 5) == 0) + smtp_sasl_helo_auth(state, word + 5); #endif else if (strcasecmp(word, var_myhostname) == 0) { msg_warn("host %s replied to HELO/EHLO with my own hostname %s", diff --git a/postfix/src/smtp/smtp_trouble.c b/postfix/src/smtp/smtp_trouble.c index 0085bda69..d9128f1f5 100644 --- a/postfix/src/smtp/smtp_trouble.c +++ b/postfix/src/smtp/smtp_trouble.c @@ -133,7 +133,7 @@ static void smtp_check_code(SMTP_STATE *state, int code) * anti-UCE systems, by people who aren't aware of RFC details. */ if ((!SMTP_SOFT(code) && !SMTP_HARD(code)) - || code == 555 /* RFC 1869, section 6.1. */ + || code == 555 /* RFC 1869, section 6.1. */ || (code >= 500 && code < 510)) state->error_mask |= MAIL_ERROR_PROTOCOL; } diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 6f4703ed4..970d869fc 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -57,6 +57,10 @@ /* .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 +/* 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". /* .SH "Content inspection controls" /* .IP \fBcontent_filter\fR /* The name of a mail delivery transport that filters mail and that @@ -343,6 +347,7 @@ bool var_smtpd_sasl_enable; char *var_smtpd_sasl_opts; char *var_smtpd_sasl_realm; char *var_filter_xport; +bool var_broken_auth_clients; /* * Global state, for stand-alone mode queue file cleanup. When this is @@ -439,8 +444,11 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) smtpd_chat_reply(state, "250-SIZE"); smtpd_chat_reply(state, "250-ETRN"); #ifdef USE_SASL_AUTH - if (var_smtpd_sasl_enable) + if (var_smtpd_sasl_enable) { smtpd_chat_reply(state, "250-AUTH %s", state->sasl_mechanism_list); + if (var_broken_auth_clients) + smtpd_chat_reply(state, "250-AUTH=%s", state->sasl_mechanism_list); + } #endif smtpd_chat_reply(state, "250 8BITMIME"); return (0); @@ -949,7 +957,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) state->error_mask |= MAIL_ERROR_BOUNCE; smtpd_chat_reply(state, "554 Error: too many hops"); } else if ((state->err & CLEANUP_STAT_CONT) != 0) { - state->error_mask |= MAIL_ERROR_BOUNCE; + state->error_mask |= MAIL_ERROR_POLICY; smtpd_chat_reply(state, "552 Error: content rejected"); } else if ((state->err & CLEANUP_STAT_WRITE) != 0) { state->error_mask |= MAIL_ERROR_RESOURCE; @@ -1447,6 +1455,7 @@ int main(int argc, char **argv) VAR_DISABLE_VRFY_CMD, DEF_DISABLE_VRFY_CMD, &var_disable_vrfy_cmd, VAR_ALLOW_UNTRUST_ROUTE, DEF_ALLOW_UNTRUST_ROUTE, &var_allow_untrust_route, VAR_SMTPD_SASL_ENABLE, DEF_SMTPD_SASL_ENABLE, &var_smtpd_sasl_enable, + VAR_BROKEN_AUTH_CLNTS, DEF_BROKEN_AUTH_CLNTS, &var_broken_auth_clients, 0, }; static CONFIG_STR_TABLE str_table[] = { diff --git a/postfix/src/smtpstone/smtp-sink.c b/postfix/src/smtpstone/smtp-sink.c index a10b48e8e..a41801354 100644 --- a/postfix/src/smtpstone/smtp-sink.c +++ b/postfix/src/smtpstone/smtp-sink.c @@ -329,12 +329,19 @@ static void disconnect(SINK_STATE *state) static void connect_event(int unused_event, char *context) { int sock = CAST_CHAR_PTR_TO_INT(context); + struct sockaddr sa; + SOCKADDR_SIZE len = sizeof(sa); SINK_STATE *state; int fd; - if ((fd = accept(sock, (struct sockaddr *) 0, (SOCKADDR_SIZE *) 0)) >= 0) { + if ((fd = accept(sock, &sa, &len)) >= 0) { if (msg_verbose) - msg_info("connect"); + msg_info("connect (%s)", sa.sa_family == AF_LOCAL ? "AF_LOCAL" : +#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)); state->stream = vstream_fdopen(fd, O_RDWR); diff --git a/postfix/src/smtpstone/smtp-source.c b/postfix/src/smtpstone/smtp-source.c index c5d9dbcc7..6ab916429 100644 --- a/postfix/src/smtpstone/smtp-source.c +++ b/postfix/src/smtpstone/smtp-source.c @@ -136,10 +136,11 @@ static const char *var_myhostname; static int session_count; static int message_count = 1; static struct sockaddr_in sin; + #undef sun static struct sockaddr_un sun; static struct sockaddr *sa; -static int sa_len; +static int sa_length; static int recipients = 1; static char *defaddr; static char *recipient; @@ -398,7 +399,7 @@ static void start_connect(SESSION *session) session->stream = vstream_fdopen(fd, O_RDWR); event_enable_write(fd, connect_done, (char *) session); smtp_timeout_setup(session->stream, var_timeout); - if (connect(fd, sa, sa_len) < 0 && errno != EINPROGRESS) + if (connect(fd, sa, sa_length) < 0 && errno != EINPROGRESS) fail_connect(session); } @@ -842,7 +843,7 @@ int main(int argc, char **argv) #endif memcpy(sun.sun_path, path, path_len); sa = (struct sockaddr *) & sun; - sa_len = sizeof(sun); + sa_length = sizeof(sun); } else { if (strncmp(argv[optind], "inet:", 5) == 0) argv[optind] += 5; @@ -853,7 +854,7 @@ int main(int argc, char **argv) sin.sin_addr.s_addr = find_inet_addr(host); sin.sin_port = find_inet_port(port, "tcp"); sa = (struct sockaddr *) & sin; - sa_len = sizeof(sin); + sa_length = sizeof(sin); } /* diff --git a/postfix/src/util/Makefile.in b/postfix/src/util/Makefile.in index 35ac25f54..8d8c53b63 100644 --- a/postfix/src/util/Makefile.in +++ b/postfix/src/util/Makefile.in @@ -383,18 +383,6 @@ 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_env.o: dict_env.c dict_env.o: sys_defs.h dict_env.o: mymalloc.h @@ -418,14 +406,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 diff --git a/postfix/src/util/make_dirs.c b/postfix/src/util/make_dirs.c index 1ca68af13..b3efcddbf 100644 --- a/postfix/src/util/make_dirs.c +++ b/postfix/src/util/make_dirs.c @@ -81,8 +81,18 @@ int make_dirs(const char *path, int perms) } else { if (errno != ENOENT) break; - if ((ret = mkdir(saved_path, perms)) < 0 && errno != EEXIST) - break; + if ((ret = mkdir(saved_path, perms)) < 0) { + if (errno != EEXIST) + break; + /* Race condition? */ + if ((ret = stat(saved_path, &st)) < 0) + break; + if (!S_ISDIR(st.st_mode)) { + errno = ENOTDIR; + ret = -1; + break; + } + } } if (saved_ch != 0) *cp = saved_ch; diff --git a/postfix/src/virtual/.indent.pro b/postfix/src/virtual/.indent.pro deleted file mode 120000 index 5c837eca6..000000000 --- a/postfix/src/virtual/.indent.pro +++ /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 index 9517501e0..000000000 --- a/postfix/src/virtual/Makefile.in +++ /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 index 63b15580f..000000000 --- a/postfix/src/virtual/deliver_attr.c +++ /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 - -/* Utility library. */ - -#include -#include - -/* 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 index 9dfca28a1..000000000 --- a/postfix/src/virtual/mailbox.c +++ /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 -#include -#include -#include - -/* Utility library. */ - -#include -#include -#include -#include -#include -#include - -/* Global library. */ - -#include -#include -#include -#include -#include - -#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 index 4aa0c6756..000000000 --- a/postfix/src/virtual/maildir.c +++ /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 - -/* Utility library. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Global library. */ - -#include -#include -#include -#include - -/* 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 index 725108f5b..000000000 --- a/postfix/src/virtual/recipient.c +++ /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 - -/* Utility library. */ - -#include -#include -#include - -/* Global library. */ - -#include - -/* 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 index 8989046e0..000000000 --- a/postfix/src/virtual/unknown.c +++ /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 - -/* Utility library. */ - -#include - -/* Global library. */ - -#include - -/* 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.c b/postfix/src/virtual/virtual.c deleted file mode 100644 index 87a71d3ca..000000000 --- a/postfix/src/virtual/virtual.c +++ /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 - -/* Utility library. */ - -#include -#include -#include -#include -#include -#include - -/* Global library. */ - -#include -#include -#include -#include -#include -#include -#include - -/* Single server skeleton. */ - -#include - -/* 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 index 1443bc8d0..000000000 --- a/postfix/src/virtual/virtual.h +++ /dev/null @@ -1,134 +0,0 @@ -/*++ -/* NAME -/* virtual 3h -/* SUMMARY -/* virtual mail delivery -/* SYNOPSIS -/* #include "virtual.h" -/* DESCRIPTION -/* .nf - - /* - * System library. - */ -#include - - /* - * Utility library. - */ -#include -#include - - /* - * Global library. - */ -#include -#include -#include - - /* - * 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 -/*--*/