]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
snapshot-20011121
authorWietse Venema <wietse@porcupine.org>
Wed, 21 Nov 2001 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:27:37 +0000 (06:27 +0000)
94 files changed:
postfix/HISTORY
postfix/INSTALL
postfix/Makefile.in
postfix/RELEASE_NOTES
postfix/conf/main.cf
postfix/conf/sample-aliases.cf
postfix/conf/sample-auth.cf
postfix/conf/sample-canonical.cf
postfix/conf/sample-debug.cf
postfix/conf/sample-lmtp.cf
postfix/conf/sample-local.cf
postfix/conf/sample-misc.cf
postfix/conf/sample-relocated.cf
postfix/conf/sample-rewrite.cf
postfix/conf/sample-smtp.cf
postfix/conf/sample-smtpd.cf
postfix/conf/sample-transport.cf
postfix/conf/sample-virtual.cf
postfix/html/flush.8.html
postfix/html/smtpd.8.html
postfix/html/transport.5.html
postfix/html/trivial-rewrite.8.html
postfix/html/uce.html
postfix/html/virtual.8.html
postfix/makedefs
postfix/man/man5/transport.5
postfix/man/man8/flush.8
postfix/man/man8/smtpd.8
postfix/man/man8/trivial-rewrite.8
postfix/man/man8/virtual.8
postfix/proto/transport
postfix/src/flush/Makefile.in
postfix/src/flush/flush.c
postfix/src/global/Makefile.in
postfix/src/global/debug_peer.c
postfix/src/global/deliver_pass.c
postfix/src/global/deliver_request.c
postfix/src/global/domain_list.c
postfix/src/global/domain_list.h
postfix/src/global/mail_params.c
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/global/match_parent_style.c [new file with mode: 0644]
postfix/src/global/match_parent_style.h [new file with mode: 0644]
postfix/src/global/namadr_list.c
postfix/src/global/namadr_list.h
postfix/src/global/resolve_local.c
postfix/src/global/string_list.c
postfix/src/global/string_list.h
postfix/src/lmtp/Makefile.in
postfix/src/local/file.c
postfix/src/local/mailbox.c
postfix/src/local/maildir.c
postfix/src/nqmgr/qmgr_deliver.c
postfix/src/postconf/Makefile.in
postfix/src/qmgr/qmgr_deliver.c
postfix/src/qmqpd/Makefile.in
postfix/src/qmqpd/qmqpd.c
postfix/src/sendmail/sendmail.c
postfix/src/smtp/Makefile.in
postfix/src/smtp/smtp_proto.c
postfix/src/smtpd/Makefile.in
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd.h
postfix/src/smtpd/smtpd_check.c
postfix/src/smtpd/smtpd_check.in
postfix/src/smtpd/smtpd_check.in2
postfix/src/smtpd/smtpd_check.ref
postfix/src/smtpd/smtpd_check.ref2
postfix/src/smtpd/smtpd_state.c
postfix/src/smtpstone/smtp-sink.c
postfix/src/trivial-rewrite/transport.c
postfix/src/trivial-rewrite/trivial-rewrite.c
postfix/src/util/Makefile.in
postfix/src/util/attr.h
postfix/src/util/attr_print0.c [new file with mode: 0644]
postfix/src/util/attr_print64.c [moved from postfix/src/util/attr_print.c with 63% similarity]
postfix/src/util/attr_scan0.c [new file with mode: 0644]
postfix/src/util/attr_scan0.ref [new file with mode: 0644]
postfix/src/util/attr_scan64.c [moved from postfix/src/util/attr_scan.c with 77% similarity]
postfix/src/util/attr_scan64.ref [new file with mode: 0644]
postfix/src/util/inet_trigger.c
postfix/src/util/iostuff.h
postfix/src/util/make_dirs.c
postfix/src/util/match_list.c
postfix/src/util/match_list.h
postfix/src/util/match_ops.c
postfix/src/util/match_ops.h
postfix/src/util/sock_empty_wait.c [new file with mode: 0644]
postfix/src/util/stream_trigger.c
postfix/src/util/unix_trigger.c
postfix/src/util/vstring_vstream.c
postfix/src/util/vstring_vstream.h
postfix/src/virtual/virtual.c

index 85da312693dc84183365001549e2c8485ecec167..8dee622e0dd1b6c9f9ea6eb434c47c554e1b5525 100644 (file)
@@ -5576,6 +5576,44 @@ Apologies for any names omitted.
        Bugfix: missing terminator in new attribute-based function
        call caused signal 11. File: src/cleanup/cleanup.c.
 
+       Lame workaround for ESTALE errors with mail delivery over
+       NFS. Additional bandages were added to the local delivery
+       agent. However, Wietse maintains that Postfix offers no
+       guarantee for reliable delivery over NFS.
+
+       Feature: put "warn_if_reject" before an smtpd restriction,
+       and that restriction logs warnings without rejecting mail.
+       This makes it easier to test configurations "live" without
+       having to lose mail. File: smtpd/smtpd_check.c.
+
+20011107
+
+       Workaround: in order to get mail past PIX firewall bugs,
+       the Postfix SMTP client now blocks until the socket send
+       buffer is empty before sending the final ".<CR><LF>". Files:
+       util/sock_empty_wait.c, smtp/smtp_proto.c. Changed into
+       sleep(10) on 20011119. Sleep suggested by Hobbit.
+
+20011108
+
+       Feature: added string-null encoding for internal protocols.
+       Files: util/attr_print0.c, util/attr_scan0.c.
+
+       Feature: configurable parent domain matching for domain
+       and hostname/address match lists: either .domain or the
+       domain name itself. Files: util/match_ops.c util/match_list.c
+
+       Feature: added pretend-to-be-behind-PIX mode to the smtp-sink
+       test program, in order to stress test some PIX bug workaround
+       code.
+
+20011109
+
+       Workaround: Linux and Solaris systems have no reasonable
+       way to block until a socket drains. On these systems Postfix
+       simply waits for 10 seconds, in order to work around PIX
+       ".<CR><LF>" bugs.  File: util/sock_empty_wait.c.
+
 20011114
 
        Bugfix: reset the smtpd command transaction log between
@@ -5583,20 +5621,49 @@ Apologies for any names omitted.
 
 20011115
 
+       Feature: mailbox_command_maps no longer requires that every
+       user has an entry. If the user does not have a command
+       entry, the local delivery agent tries the other delivery
+       methods (mailbox_command, home_mailbox).  File: local/mailbox.c.
+
        Bugfix: reset the smtpd command transaction log between
        non-deliveries. File: smtpd/smtpd.c.
 
 20011116
 
-       Bugfix: consolidated all the command transaction log 
-       resets and eliminated one other case (Victor Duchovny,
-       Morgan Stanley). File: smtpd/smtpd.c.
+       Bugfix: consolidated all the command transaction log resets
+       and eliminated one missing reset (Victor Duchovny, Morgan
+       Stanley). File: smtpd/smtpd.c.
+
+20011118
+
+       Cleanup: replaced unnecessary match_list wrapper code by
+       macros. Files:  global/{string,domain,namadr}_list.[hc].
+
+20011119
+
+       Feature: configurable parent domain matching strategy for
+       transport map lookups. File:  trivial-rewrite/transport.c.
+
+       New parent_domain_matches_subdomains parameter. This lists
+       all the Postfix features where a domain name matches itself
+       and all its subdomains (instead of requiring ".domain.name"
+       for subdomain matches).  Planning for future backwards
+       compatibility :-)  File:  global/match_parent_style.c.
+
+       Workaround: simplified the PIX ".<CR><LF>" bug to always
+       sleep for 10 seconds.  File: smtp/smtp_proto.c.
 
 20011120
 
        Workaround: disable attribute string length restriction so
        that trivial-rewrite does not refuse to rewrite broken mail
-       headers.  File:  util/attr_scan.c.
+       headers.  Files:  util/attr_scan*.c.
+
+20011121
+
+       Bugfix: missing long integer support in the new IPC protocols.
+       Files: util/attr_scan*.c, util/attr_print*.c.
 
 Open problems:
 
@@ -5609,6 +5676,8 @@ Open problems:
        Medium: smtpd access maps don't understand the recipient
        delimiter setting.
 
+       Low: default domain for appending to unqualified recipients.
+
        Low: The $process_id_directory setting is not used anywhere
        in Postfix. Problem reported by Michael Smith, texas.net.
        This should be documented, or better, the code should warn
index 3d6748521995348b70482212514fd164c790376d..8c5419b22c168197ab5a2348292fa9b0c99b4e99 100644 (file)
@@ -213,8 +213,8 @@ In order to install or upgrade Postfix:
 
 - Run the INSTALL.sh script as the super-user:
 
-    # make install              (interactive version, first time install)
-    # make install </dev/null   (non-interactive version, for upgrades)
+    # make install       (interactive version, first time install)
+    # make upgrade       (non-interactive version, for upgrades)
 
   The non-interactive version needs the /etc/postfix/install.cf
   file from a previous installation. If the file does not exist,
index 62d3af31d3b0d297c64eb02b272d583a3a69b9bd..b20bb4cb50c1058b2453f379f46fcb8b0a53de27 100644 (file)
@@ -27,6 +27,9 @@ printfck: update
 install: update
        sh INSTALL.sh
 
+upgrade: update
+       sh INSTALL.sh </dev/null
+
 depend clean:
        set -e; for i in $(DIRS); do \
         (set -e; echo "[$$i]"; cd $$i; $(MAKE) $@) || exit 1; \
index d4fae5c2e2bcef0d86683a14526b295a5f6acf9e..77bb959f8f00f9e6e4e3316b22910b72ce581597 100644 (file)
@@ -1,7 +1,32 @@
-Snapshot 20011103 introduces a negligible amount of features and
-is all about revision of Postfix internals. With more than 70 pages
-of context diffs compared to the previous snapshot, this release
-is a baseline for upcoming feature changes.
+Incompatible changes with snapshot-20011121
+===========================================
+
+The internal protocols have changed again, so you must "postfix
+reload" if upgrading from a previous release. The change is from
+base64 encoded strings to null-terminated strings (Postfix now
+supports multiple encodings).
+
+Major changes with snapshot-20011121
+====================================
+
+Configurable host/domain name wildcard matching behavior: choice
+between "pattern `domain.name' matches string `host.domain.name'"
+(to be deprecated in the future) and "pattern `.domain.name' matches
+string `host.domain.name'" (to be preferred in the future).  The
+configuration parameter "parent_domain_matches_subdomains" specifies
+which Postfix features use the behavior that will become deprecated.
+
+New "warn_if_reject" smtpd pseudo restriction that only warns if
+the restriction that follows would reject mail. Look for file
+records that contain the string "reject_warning".
+
+Disgusting workaround for a well-known CISCO PIX firewall bug that
+causes the .<CR>LF> at the end of mail to be lost. The workaround
+has no effect for other mail deliveries.
+
+mailbox_command_maps allows you to configure the external delivery
+command per user (local delivery agent only). This feature has
+precedence over mailbox_command and home_mailbox settings.
 
 Major changes with snapshot-20011103
 ====================================
index 43220c108870455213dac93aef4fa2c9d8837239..cc39b935bbb74554b597890bc140c14fec376817 100644 (file)
@@ -152,9 +152,9 @@ mail_owner = postfix
 # Specify "mynetworks_style = host" when Postfix should "trust"
 # only the local machine.
 # 
-# mynetworks_style = class
-# mynetworks_style = subnet
-# mynetworks_style = host
+#mynetworks_style = class
+#mynetworks_style = subnet
+#mynetworks_style = host
 
 # Alternatively, you can specify the mynetworks list by hand, in
 # which case Postfix ignores the mynetworks_style setting.
@@ -217,10 +217,10 @@ mail_owner = postfix
 #
 # If you're connected via UUCP, see also the default_transport parameter.
 #
-# relayhost = $mydomain
-# relayhost = gateway.my.domain
-# relayhost = uucphost
-# relayhost = [an.ip.add.ress]
+#relayhost = $mydomain
+#relayhost = gateway.my.domain
+#relayhost = uucphost
+#relayhost = [an.ip.add.ress]
 
 # REJECTING UNKNOWN LOCAL USERS
 #
@@ -319,7 +319,7 @@ mail_owner = postfix
 # Basically, the software tries user+foo and .forward+foo before
 # trying user and .forward.
 #
-# recipient_delimiter = +
+#recipient_delimiter = +
 
 # DELIVERY TO MAILBOX
 #
@@ -335,8 +335,8 @@ mail_owner = postfix
 # UNIX-style mailboxes are kept. The default setting depends on the
 # system type.
 #
-# mail_spool_directory = /var/mail
-# mail_spool_directory = /var/spool/mail
+#mail_spool_directory = /var/mail
+#mail_spool_directory = /var/spool/mail
 
 # The mailbox_command parameter specifies the optional external
 # command to use instead of mailbox delivery. The command is run as
@@ -399,9 +399,9 @@ mail_owner = postfix
 #
 # luser_relay works only for the default Postfix local delivery agent.
 #
-# luser_relay = $user@other.host
-# luser_relay = $local@other.host
-# luser_relay = admin+$local
+#luser_relay = $user@other.host
+#luser_relay = $local@other.host
+#luser_relay = admin+$local
   
 # JUNK MAIL CONTROLS
 # 
@@ -481,8 +481,8 @@ debug_peer_level = 2
 # increase the verbose logging level by the amount specified in the
 # debug_peer_level parameter.
 #
-# debug_peer_list = 127.0.0.1
-# debug_peer_list = some.domain
+#debug_peer_list = 127.0.0.1
+#debug_peer_list = some.domain
 
 # The debugger_command specifies the external command that is executed
 # when a Postfix daemon program is run with the -D option.
index 80dd4a6e82ecaefa1fa73494ad4a55b7ce7bf148..6ebebb66de1bdc23a6b02f939eb7bcea9b8a36fd 100644 (file)
@@ -13,8 +13,8 @@
 # specify multiple tables, not necessarily all under control by
 # Postfix.
 #
-# alias_database = dbm:/etc/aliases
-# alias_database = dbm:/etc/mail/aliases
+#alias_database = dbm:/etc/aliases
+#alias_database = dbm:/etc/mail/aliases
 alias_database = hash:/etc/aliases
 
 # The alias_maps parameter specifies the list of alias databases used
@@ -30,6 +30,6 @@ alias_database = hash:/etc/aliases
 # It will take a minute or so before changes become visible.  Use
 # "postfix reload" to eliminate the delay.
 # 
-# alias_maps = dbm:/etc/aliases, nis:mail.aliases
-# alias_maps = hash:/etc/aliases
+#alias_maps = dbm:/etc/aliases, nis:mail.aliases
+#alias_maps = hash:/etc/aliases
 alias_maps = hash:/etc/aliases
index be003437de8e5b2cad5ac8184105b65bf6e4e1fa..00920bde736975f51d2d1036e2d0698c1645387c 100644 (file)
@@ -70,7 +70,7 @@ smtpd_sasl_security_options = noanonymous
 # By default, the local authentication realm name is the name of the
 # machine.
 # 
-# smtpd_sasl_local_domain = $mydomain
+#smtpd_sasl_local_domain = $mydomain
 smtpd_sasl_local_domain = $myhostname
 
 # SMTP CLIENT CONTROLS
index 1e3b0a57c8c07bce02a8921b65294d9fd19a2d4f..474976b70a8c08401e59ba6fc3cd6613d5376954 100644 (file)
 # will become visible after a minute or so.  Use "postfix reload"
 # to eliminate the delay.
 #
-# canonical_maps = dbm:/etc/postfix/canonical
-# canonical_maps = hash:/etc/postfix/canonical
-# canonical_maps = hash:/etc/postfix/canonical, nis:canonical
-# canonical_maps = hash:/etc/postfix/canonical, netinfo:/canonical
+#canonical_maps = dbm:/etc/postfix/canonical
+#canonical_maps = hash:/etc/postfix/canonical
+#canonical_maps = hash:/etc/postfix/canonical, nis:canonical
+#canonical_maps = hash:/etc/postfix/canonical, netinfo:/canonical
 canonical_maps = 
 
 # The recipient_canonical_maps parameter specifies optional address
@@ -30,7 +30,7 @@ canonical_maps =
 #
 # $recipient_canonical_maps is used before $canonical_maps lookups.
 #
-# recipient_canonical_maps = hash:/etc/postfix/recipient_canonical
+#recipient_canonical_maps = hash:/etc/postfix/recipient_canonical
 recipient_canonical_maps = 
 
 # The sender_canonical_maps parameter specifies optional address
@@ -44,5 +44,5 @@ recipient_canonical_maps =
 # 
 # $sender_canonical_maps is used before $canonical_maps lookups.
 #
-# sender_canonical_maps = hash:/etc/postfix/sender_canonical
+#sender_canonical_maps = hash:/etc/postfix/sender_canonical
 sender_canonical_maps = 
index c8a8e97a66c8e941e34d8fe4c808db8c012597a1..5f850ddc751355aa095145b9ab8340025c2ae513 100644 (file)
@@ -16,8 +16,8 @@ debug_peer_level = 2
 # increase the verbose logging level by the amount specified in the
 # debug_peer_level parameter.
 #
-# debug_peer_list = 127.0.0.1
-# debug_peer_list = some.domain
+#debug_peer_list = 127.0.0.1
+#debug_peer_list = some.domain
 debug_peer_list = 
 
 # The debugger_command specifies the external command that is executed
index 64419a35b361c7ee7aab35a7df47470f650ce4db..9e2699cccbd3b0e46d12a47149350f3ced8beccf 100644 (file)
@@ -68,7 +68,7 @@ lmtp_destination_recipient_limit = $default_destination_recipient_limit
 # Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
 # The default time unit is s (seconds).
 #
-# lmtp_connect_timeout = 30s
+#lmtp_connect_timeout = 30s
 lmtp_connect_timeout = 0s
 
 # The lmtp_lhlo_timeout parameter specifies the LMTP client timeout
index 69f87dda1833938335d4ee4fe78d4f6e506d72e0..a64e531f9faf28a5d8cf7e1a44ed5539c6218bc3 100644 (file)
@@ -6,6 +6,10 @@
 # 
 # See the sample-aliases.cf file for parameters that are specific to
 # alias database lookup.
+#
+# Mailbox delivery is controlled by a series of parameters. The
+# precedence, from highest to lowest priority: mailbox_transport,
+# mailbox_command_maps, mailbox_command, home_mailbox.
 
 # The biff parameter specifies whether or not to contact the biff
 # server.  This server sends "new mail" notifications to users who
@@ -15,7 +19,7 @@
 # with lots of interactive users, this "protocol" can be a real
 # performance pig.  Specify "biff = no" to disable.
 # 
-# biff = no
+#biff = no
 biff = yes
 
 # The require_home_directory parameter controls whether a local
@@ -84,14 +88,14 @@ forward_path = $home/.forward$recipient_delimiter$extension,$home/.forward
 # external commands. The default is to disallow delivery to "|command"
 # in :include: files.
 #
-# allow_mail_to_commands = alias,forward,include
+#allow_mail_to_commands = alias,forward,include
 allow_mail_to_commands = alias,forward
 
 # The allow_mail_to_files parameter restricts mail delivery to external
 # file. The default is to disallow delivery to /file/name in :include:
 # files.
 #
-# allow_mail_to_files = alias,forward,include
+#allow_mail_to_files = alias,forward,include
 allow_mail_to_files = alias,forward
 
 # The default_privs parameter specifies the default rights used by
@@ -110,8 +114,8 @@ default_privs = nobody
 # mailbox file is /var/spool/mail/user or /var/mail/user.  Specify
 # "Maildir/" for qmail-style delivery (the / is required).
 #
-# home_mailbox = Mailbox
-# home_mailbox = Maildir/
+#home_mailbox = Mailbox
+#home_mailbox = Maildir/
 home_mailbox = 
 
 # The luser_relay parameter specifies an optional destination address
@@ -127,16 +131,16 @@ home_mailbox =
 #
 # luser_relay works only for the default Postfix local delivery agent.
 #
-# luser_relay = $user@other.host
-# luser_relay = $local@other.host
-# luser_relay = admin+$local
+#luser_relay = $user@other.host
+#luser_relay = $local@other.host
+#luser_relay = admin+$local
 
 # The mail_spool_directory parameter specifies the directory where
 # UNIX-style mailboxes are kept. The default setting depends on the
 # system type.
 #
-# mail_spool_directory = /var/mail
-# mail_spool_directory = /var/spool/mail
+#mail_spool_directory = /var/mail
+#mail_spool_directory = /var/spool/mail
 
 # The mailbox_command parameter specifies the optional external
 # command to use instead of mailbox delivery. The command is run
@@ -157,16 +161,17 @@ home_mailbox =
 # IF YOU USE THIS TO DELIVER MAIL SYSTEM-WIDE, YOU MUST SET UP AN
 # ALIAS THAT FORWARDS MAIL FOR ROOT TO A REAL USER.
 #
-# mailbox_command = /some/where/procmail
-# mailbox_command = /some/where/procmail -a "$EXTENSION"
+#mailbox_command = /some/where/procmail
+#mailbox_command = /some/where/procmail -a "$EXTENSION"
 mailbox_command = 
 
 # The mailbox_command_maps allows you to specify a per-user mailbox
 # command. The maps are keyed by username (not including the domain).
-# Specify one or more maps. If this feature is used then every user
-# must have a matching entry.
+# Specify one or more maps. If a user is not found in the maps then
+# lower precedence delivery mechanisms take effect. See the top of
+# this file for the precedences of mailbox delivery mechanisms.
 #
-# mailbox_command_maps = hash:/etc/postfix/mailbox_commands
+#mailbox_command_maps = hash:/etc/postfix/mailbox_commands
 
 # The mailbox_transport specifies the optional transport in master.cf
 # to use after processing aliases and .forward files. This parameter
@@ -178,8 +183,8 @@ mailbox_command =
 # :nexthop part is optional. For more details see the sample transport
 # configuration file.
 #
-# mailbox_transport = lmtp:unix:/file/name
-# mailbox_transport = cyrus
+#mailbox_transport = lmtp:unix:/file/name
+#mailbox_transport = cyrus
 mailbox_transport =
 
 # The fallback_transport specifies the optional transport in master.cf
@@ -191,8 +196,8 @@ mailbox_transport =
 # :nexthop part is optional. For more details see the sample transport
 # configuration file.
 #
-# fallback_transport = lmtp:unix:/file/name
-# fallback_transport = cyrus
+#fallback_transport = lmtp:unix:/file/name
+#fallback_transport = cyrus
 fallback_transport =
 
 #
@@ -236,5 +241,5 @@ local_destination_recipient_limit = 1
 # and command. Turning off the Delivered-To: header when forwarding
 # mail is not recommended.
 #
-# prepend_delivered_header = command, file, forward
-# prepend_delivered_header = forward
+#prepend_delivered_header = command, file, forward
+#prepend_delivered_header = forward
index 4b2d7d502f50fb9b28cd99f04881bbe6a616c991..f756321660bcc69659b67944da9fb65b47aec7f0 100644 (file)
@@ -24,8 +24,8 @@ daemon_timeout = 18000s
 # systems the default type is either `dbm' or `hash'. The default is
 # determined when the Postfix system is built.
 #
-# default_database_type = hash
-# default_database_type = dbm
+#default_database_type = hash
+#default_database_type = dbm
 
 # The default_transport parameter specifies the default message
 # delivery transport to use when no transport is explicitly given in
@@ -36,7 +36,7 @@ daemon_timeout = 18000s
 # transport or nexthop are optional. For more details see the sample
 # transports file.
 #
-# default_transport = uucp:relayhostname
+#default_transport = uucp:relayhostname
 default_transport = smtp
 
 # The double_bounce_sender parameter specifies the sender address
@@ -98,7 +98,7 @@ hopcount_limit = 50
 # 
 # Specify a list of names separated by whitespace or comma.
 #
-# import_environment = MAIL_CONFIG TZ XAUTHORITY DISPLAY HOME PURIFYOPTIONS
+#import_environment = MAIL_CONFIG TZ XAUTHORITY DISPLAY HOME PURIFYOPTIONS
 import_environment = MAIL_CONFIG MAIL_DEBUG MAIL_LOGTAG TZ XAUTHORITY DISPLAY
 
 # The inet_interfaces parameter specifies the network interface
@@ -127,7 +127,7 @@ ipc_idle = 100s
 # Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
 # The default time unit is s (seconds).
 #
-#ipc_timeout = 3600s
+ipc_timeout = 3600s
 
 # The mail_name parameter specifies the mail system name that is used
 # in Received: headers, in the SMTP greeting banner, and in bounced
@@ -187,8 +187,8 @@ max_use = 100
 # a name matches a lookup key.  Continue long lines by starting the
 # next line with whitespace.
 #
-# mydestination = $myhostname, localhost.$mydomain $mydomain
-# mydestination = $myhostname, localhost.$mydomain www.$mydomain, ftp.$mydomain
+#mydestination = $myhostname, localhost.$mydomain $mydomain
+#mydestination = $myhostname, localhost.$mydomain www.$mydomain, ftp.$mydomain
 mydestination = $myhostname, localhost.$mydomain
 
 # The mydomain parameter specifies the local internet domain name.
@@ -212,7 +212,7 @@ mydestination = $myhostname, localhost.$mydomain
 # a domain-wide alias database that aliases each user to
 # user@that.users.mailhost.
 #
-# myorigin = $mydomain
+#myorigin = $mydomain
 myorigin = $myhostname
 
 # The mynetworks parameter specifies the list of "trusted" SMTP
@@ -237,9 +237,9 @@ myorigin = $myhostname
 # Specify "mynetworks_style = host" when Postfix should "trust"
 # only the local machine.
 # 
-# mynetworks_style = class
-# mynetworks_style = subnet
-# mynetworks_style = host
+#mynetworks_style = class
+#mynetworks_style = subnet
+#mynetworks_style = host
 
 # Alternatively, you can specify the mynetworks list by hand, in
 # which case Postfix ignores the mynetworks_style setting.
@@ -259,8 +259,8 @@ myorigin = $myhostname
 # policy (anti-UCE violations) and protocol error (broken mailers)
 # reports.
 #
-# notify_classes = bounce,delay,policy,protocol,resource,software
-# notify_classes = 2bounce,resource,software
+#notify_classes = bounce,delay,policy,protocol,resource,software
+#notify_classes = 2bounce,resource,software
 notify_classes = resource,software
 
 # The following parameters specify who gets postmaster notices if
@@ -272,6 +272,16 @@ bounce_notice_recipient = postmaster
 delay_notice_recipient = postmaster
 error_notice_recipient = postmaster
 
+# The parent_domain_matches_subdomains parameter specifies what
+# Postfix features use "domain.name matches sub.domain.name" style
+# pattern matching instead of requiring ".domain.name". This is
+# planned backwards compatibility: eventually, all Postfix features
+# are expected to require ".domain.name" style patterns.
+#
+parent_domain_matches_subdomains = debug_peer_list,fast_flush_domains,
+       mynetworks,permit_mx_backup_networks,qmqpd_authorized_clients,
+       relay_domains,smtpd_access_maps
+
 # The process_id_directory specifies a lock file directory relative
 # to the Postfix queue directory. This facility is used by the master
 # daemon to lock out other master daemon instances.
@@ -297,7 +307,7 @@ queue_directory = /var/spool/postfix
 # Basically, the software tries user+foo and .forward+foo before
 # trying user and .forward.
 #
-# recipient_delimiter = +
+#recipient_delimiter = +
 recipient_delimiter =
 
 # The propagate_unmatched_extensions parameter specifies what lookup
@@ -332,10 +342,10 @@ recipient_delimiter =
 #
 # If you're connected via UUCP, see also the default_transport parameter.
 #
-# relayhost = $mydomain
-# relayhost = gateway.my.domain
-# relayhost = uucphost
-# relayhost = [an.ip.add.ress]
+#relayhost = $mydomain
+#relayhost = gateway.my.domain
+#relayhost = uucphost
+#relayhost = [an.ip.add.ress]
 relayhost =
 
 # The relocated_maps parameter specifies optional tables with contact
@@ -347,7 +357,7 @@ relayhost =
 # Specify the types and names of databases to use.  After change,
 # run "postmap /etc/postfix/relocated", then "postfix reload".
 #
-# relocated_maps = hash:/etc/postfix/relocated
+#relocated_maps = hash:/etc/postfix/relocated
 relocated_maps =
 
 # The syslog_facility parameter controls where Postfix logging is
@@ -390,4 +400,4 @@ trigger_timeout = 10s
 # Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
 # The default time unit is h (hours).
 #
-# delay_warning_time = 0h
+#delay_warning_time = 0h
index 1c83ca53877a5b11822e5fe3c783a9cf057875be..611134b0a64327ca571d3758f36abe48e7acbf67 100644 (file)
@@ -14,8 +14,8 @@
 # build the necessary DBM or DB file after change, then "postfix
 # reload" to make the changes visible.
 #
-# relocated_maps = dbm:/etc/postfix/relocated
-# relocated_maps = hash:/etc/postfix/relocated
-# relocated_maps = hash:/etc/postfix/relocated, nis:virtual
-# relocated_maps = hash:/etc/postfix/relocated, netinfo:/relocated
+#relocated_maps = dbm:/etc/postfix/relocated
+#relocated_maps = hash:/etc/postfix/relocated
+#relocated_maps = hash:/etc/postfix/relocated, nis:virtual
+#relocated_maps = hash:/etc/postfix/relocated, netinfo:/relocated
 relocated_maps = 
index deed2785fb0137d2ce5bd28ee539b81c5627051a..c4d5e1ea1943af46dbcf85de90a828cf9818e246 100644 (file)
@@ -7,7 +7,7 @@
 # The allow_percent_hack parameter controls the rewriting of the form
 # "user%domain" to "user@domain". This is enabled by default.
 #
-# allow_percent_hack = no
+#allow_percent_hack = no
 allow_percent_hack = yes
 
 # The append_at_myorigin controls the rewriting of the form "user" to
@@ -18,7 +18,7 @@ append_at_myorigin = yes
 # The append_dot_mydomain controls the rewriting of the form
 # "user@host" to "user@host.$mydomain". This is enabled by default.
 #
-# append_dot_mydomain = no
+#append_dot_mydomain = no
 append_dot_mydomain = yes
 
 # The empty_address_recipient specifies the destination for mail from
@@ -45,7 +45,7 @@ masquerade_classes = envelope_sender, header_sender, header_recipient
 #
 # By default, address masquerading is disabled.
 #
-# masquerade_domains = $mydomain
+#masquerade_domains = $mydomain
 masquerade_domains = 
 
 # The masquerade_exceptions parameter gives an optional list of user
@@ -61,5 +61,5 @@ masquerade_exceptions =
 # "site!user" to "user@site".  This is necessary if your machine is
 # connected to UUCP networks. It is enabled by default.
 #
-# swap_bangpath = no
+#swap_bangpath = no
 swap_bangpath = yes
index b1ffef7255ca8cf782d29969fdc83f258ec55450..888c49449b741070cc08fdb1cadfc00ae2ff8db7 100644 (file)
@@ -138,7 +138,7 @@ smtp_destination_recipient_limit = $default_destination_recipient_limit
 # Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
 # The default time unit is s (seconds).
 #
-# smtp_connect_timeout = 30s
+#smtp_connect_timeout = 30s
 smtp_connect_timeout = 0s
 
 # The smtp_helo_timeout parameter specifies the SMTP client timeout
index ed084a94275e6e1bd83468f8c504c59b78f515e8..b594886792dbed2323c47321fc4662b34a716f9d 100644 (file)
 # status code in the SMTP greeting banner. Some people like to see
 # the mail version advertised. By default, Postfix shows no version.
 #
-# You MUST specify the $myhostname at the start of the text. When
-# the SMTP client sees its own hostname at the start of an SMTP
-# greeting banner it will report a mailer loop. That's better than
-# having a machine meltdown.
+# You MUST specify the $myhostname at the start of the text.
 #
-# smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)
+#smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)
 smtpd_banner = $myhostname ESMTP $mail_name
 
 # The smtpd_etrn_restrictions parameter restricts what clients are
-# allowed to issue the ETRN command. The present Postfix ETRN differs
-# from other ETRN implementations in that it flushes mail for all
-# destinations. This will change in the future.
+# allowed to issue the ETRN command.
+#
+# The Postfix ETRN command is available only for destinations that
+# that are eligible for the Postfix "fast flush" service. See the
+# sample-flush.cf file for details.
 #
 # The default is to allow ETRN from any host.  The following restrictions
 # are available:
@@ -45,6 +44,7 @@ smtpd_banner = $myhostname ESMTP $mail_name
 #      is listed under $maps_rbl_domains.
 #   reject: reject the request. Place this at the end of a restriction.
 #   permit: permit the request. Place this at the end of a restriction.
+#   warn_if_reject: next restriction logs a warning instead of rejecting.
 smtpd_etrn_restrictions =
 
 # The smtpd_recipient_limit parameter restricts the number of recipients
@@ -123,9 +123,9 @@ smtpd_hard_error_limit = 100
 # Specify "mynetworks_style = host" when Postfix should "trust"
 # only the local machine.
 # 
-# mynetworks_style = class
+#mynetworks_style = class
 mynetworks_style = subnet
-# mynetworks_style = host
+#mynetworks_style = host
 
 # Alternatively, you can specify the mynetworks list by hand, in
 # which case Postfix ignores the mynetworks_style setting.
@@ -158,6 +158,7 @@ mynetworks_style = subnet
 #   reject_maps_rbl: reject if the client is listed under $maps_rbl_domains.
 #   reject: reject the request. Place this at the end of a restriction.
 #   permit: permit the request. Place this at the end of a restriction.
+#   warn_if_reject: next restriction logs a warning instead of rejecting.
 #
 # Restrictions are applied in the order as specified; the first
 # restriction that matches wins.
@@ -173,7 +174,7 @@ smtpd_client_restrictions =
 # that SMTP clients must introduce themselves at the beginning of an
 # SMTP session.
 #
-# smtpd_helo_required = yes
+#smtpd_helo_required = yes
 smtpd_helo_required = no
 
 # The smtpd_helo_restrictions parameter specifies optional restrictions
@@ -195,6 +196,7 @@ smtpd_helo_required = no
 #   check_client_access maptype:mapname: see smtpd_client_restrictions.
 #   reject: reject the request. Place this at the end of a restriction.
 #   permit: permit the request. Place this at the end of a restriction.
+#   warn_if_reject: next restriction logs a warning instead of rejecting.
 #
 # Restrictions are applied in the order as specified; the first
 # restriction that matches wins.
@@ -202,8 +204,8 @@ smtpd_helo_required = no
 # Specify a list of restrictions, separated by commas and/or whitespace.
 # Continue long lines by starting the next line with whitespace.
 #
-# smtpd_helo_restrictions = permit_mynetworks, reject_invalid_hostname
-# smtpd_helo_restrictions = permit_mynetworks, reject_unknown_hostname
+#smtpd_helo_restrictions = permit_mynetworks, reject_invalid_hostname
+#smtpd_helo_restrictions = permit_mynetworks, reject_unknown_hostname
 smtpd_helo_restrictions = 
 
 # The smtpd_sender_restrictions parameter specifies optional restrictions
@@ -228,6 +230,7 @@ smtpd_helo_restrictions =
 #   reject_non_fqdn_sender: reject sender address that is not in FQDN form
 #   reject: reject the request. Place this at the end of a restriction.
 #   permit: permit the request. Place this at the end of a restriction.
+#   warn_if_reject: next restriction logs a warning instead of rejecting.
 #
 # Restrictions are applied in the order as specified; the first
 # restriction that matches wins.
@@ -235,8 +238,8 @@ smtpd_helo_restrictions =
 # Specify a list of restrictions, separated by commas and/or whitespace.
 # Continue long lines by starting the next line with whitespace.
 #
-# smtpd_sender_restrictions = reject_unknown_sender_domain
-# smtpd_sender_restrictions = reject_unknown_sender_domain, hash:/etc/postfix/access
+#smtpd_sender_restrictions = reject_unknown_sender_domain
+#smtpd_sender_restrictions = reject_unknown_sender_domain, hash:/etc/postfix/access
 smtpd_sender_restrictions = 
 
 # The smtpd_recipient_restrictions parameter specifies restrictions on
@@ -298,6 +301,7 @@ smtpd_sender_restrictions =
 #   reject_non_fqdn_recipient: reject recipient address that is not in FQDN form
 #   reject: reject the request. Place this at the end of a restriction.
 #   permit: permit the request. Place this at the end of a restriction.
+#   warn_if_reject: next restriction logs a warning instead of rejecting.
 #
 # Restrictions are applied in the order as specified; the first
 # restriction that matches wins.
index 8ecd2b56bc2206d735e0f130e73a7a3528cb7113..79d6f87d0f62af980861decf0c7033034b95bfa9 100644 (file)
@@ -11,8 +11,8 @@
 # to use.  If you use this feature, run "postmap /etc/postfix/transport"
 # after change, then "postfix reload".
 # 
-# transport_maps = dbm:/etc/postfix/transport
-# transport_maps = hash:/etc/postfix/transport
-# transport_maps = hash:/etc/postfix/transport, nis:transport
-# transport_maps = hash:/etc/postfix/transport, netinfo:/transport
+#transport_maps = dbm:/etc/postfix/transport
+#transport_maps = hash:/etc/postfix/transport
+#transport_maps = hash:/etc/postfix/transport, nis:transport
+#transport_maps = hash:/etc/postfix/transport, netinfo:/transport
 transport_maps = 
index d660d6b797be7b39f08c10e393853875d8fd2c3b..f11ccc317c355ce98a2ec7798d834a0e9d7cfeb4 100644 (file)
@@ -16,8 +16,8 @@
 # It may take a minute or so before the change becomes visible.
 # Use "postfix reload" to eliminate the delay.
 #
-# virtual_maps = dbm:/etc/postfix/virtual
-# virtual_maps = hash:/etc/postfix/virtual
-# virtual_maps = hash:/etc/postfix/virtual, nis:virtual
-# virtual_maps = hash:/etc/postfix/virtual, netinfo:/virtual
+#virtual_maps = dbm:/etc/postfix/virtual
+#virtual_maps = hash:/etc/postfix/virtual
+#virtual_maps = hash:/etc/postfix/virtual, nis:virtual
+#virtual_maps = hash:/etc/postfix/virtual, netinfo:/virtual
 virtual_maps = 
index dbd2fb0f0b54002fa4d65296dce43faf0fa8933e..19b8ab68c070dd133f5ef77bbfc2bf093413873c 100644 (file)
@@ -136,6 +136,11 @@ FLUSH(8)                                                 FLUSH(8)
               updated  in this amount of time (default time unit:
               days).
 
+       <b>parent</b><i>_</i><b>domain</b><i>_</i><b>matches</b><i>_</i><b>subdomains</b> (versions &gt;= 20011119)
+              List of Postfix features that use <i>domain.name</i>  pat-
+              terns  to  match  <i>sub.domain.name</i>  (as  opposed  to
+              requiring <i>.domain.name</i> patterns).
+
 <b>SEE</b> <b>ALSO</b>
        <a href="smtpd.8.html">smtpd(8)</a> Postfix SMTP server
        <a href="qmgr.8.html">qmgr(8)</a> Postfix queue manager
index 511567d6fc52b01a412abfb23247fa59fb8843a3..5864c13cb54fe75d3bf8bc6322b396ba8eac856f 100644 (file)
@@ -210,6 +210,11 @@ SMTPD(8)                                                 SMTPD(8)
               delays.
 
 <b>UCE</b> <b>control</b> <b>restrictions</b>
+       <b>parent</b><i>_</i><b>domain</b><i>_</i><b>matches</b><i>_</i><b>subdomains</b> (versions &gt;= 20011119)
+              List of Postfix features that use <i>domain.name</i>  pat-
+              terns  to  match  <i>sub.domain.name</i>  (as  opposed  to
+              requiring <i>.domain.name</i> patterns).
+
        <b>smtpd</b><i>_</i><b>client</b><i>_</i><b>restrictions</b>
               Restrict what clients may connect to this mail sys-
               tem.
index 10cda5432131269d9f66bf07e03ea31cabf7d054..14a5367f3f7ea778e1d544c363cce3ff6d0cab34 100644 (file)
@@ -143,6 +143,11 @@ TRANSPORT(5)                                         TRANSPORT(5)
        details  and  for  default  values. Use the <b>postfix</b> <b>reload</b>
        command after a configuration change.
 
+       <b>parent</b><i>_</i><b>domain</b><i>_</i><b>matches</b><i>_</i><b>subdomains</b> (versions &gt;= 20011119)
+              List of Postfix features that use <i>domain.name</i>  pat-
+              terns  to  match  <i>sub.domain.name</i>  (as  opposed  to
+              requiring <i>.domain.name</i> patterns).
+
        <b>transport</b><i>_</i><b>maps</b>
               List of transport lookup tables.
 
index d926f0e6079d6ef7a94bf9c3a65f9a7a7b308409..f2bf1744361875801bcba5ef905361de81a79b11 100644 (file)
@@ -110,6 +110,11 @@ TRIVIAL-REWRITE(8)                             TRIVIAL-REWRITE(8)
               Syntax is <i>transport</i>:<i>nexthop</i>; see  <a href="transport.5.html"><b>transport</b>(5)</a>  for
               details. The :<i>nexthop</i> part is optional.
 
+       <b>parent</b><i>_</i><b>domain</b><i>_</i><b>matches</b><i>_</i><b>subdomains</b> (versions &gt;= 20011119)
+              List  of Postfix features that use <i>domain.name</i> pat-
+              terns  to  match  <i>sub.domain.name</i>  (as  opposed  to
+              requiring <i>.domain.name</i> patterns).
+
        <b>relayhost</b>
               The  default host to send non-local mail to when no
               entry is matched in the <a href="transport.5.html"><b>transport</b>(5)</a> table.
index f2cb60483d34fd7e361ffa201545d58dac90029d..4b4eb37b4c16343b5b902f77a700f925904f60fe 100644 (file)
@@ -237,6 +237,8 @@ rejected requests (default: <b>554</b>).
 
 <dt> <b><a href="#reject">reject</a></b>
 
+<dt> <b><a href="#warn_if_reject">warn_if_reject</a></b>
+
 <dt> <b><a href="#reject_unauth_pipelining">reject_unauth_pipelining</a></b>
 
 <dd> See generic restrictions.
@@ -406,6 +408,8 @@ the response code for <b>REJECT</b> results (default:  <b>554</b>).
 
 <dt> <b><a href="#reject">reject</a></b>
 
+<dt> <b><a href="#warn_if_reject">warn_if_reject</a></b>
+
 <dt> <b><a href="#reject_unauth_pipelining">reject_unauth_pipelining</a></b>
 
 <dd> See generic restrictions.
@@ -570,6 +574,8 @@ response code to rejected requests (default:  <b>504</b>).
 
 <dt> <b><a href="#reject">reject</a></b>
 
+<dt> <b><a href="#warn_if_reject">warn_if_reject</a></b>
+
 <dt> <b><a href="#reject_unauth_pipelining">reject_unauth_pipelining</a></b>
 
 <dd> See generic restrictions.
@@ -839,6 +845,8 @@ response code to rejected requests (default:  <b>504</b>).
 
 <dt> <b><a href="#reject">reject</a></b>
 
+<dt> <b><a href="#warn_if_reject">warn_if_reject</a></b>
+
 <dt> <b><a href="#reject_unauth_pipelining">reject_unauth_pipelining</a></b>
 
 <dd> See generic restrictions.
@@ -937,6 +945,8 @@ the result code for rejected requests (default: <b>554</b>).
 
 <dt> <b><a href="#reject">reject</a></b>
 
+<dt> <b><a href="#warn_if_reject">warn_if_reject</a></b>
+
 <dt> <b><a href="#reject_unauth_pipelining">reject_unauth_pipelining</a></b>
 
 <dd> See generic restrictions.
@@ -979,6 +989,17 @@ specifies the response code to rejected requests (default:
 
 <p>
 
+<a name="warn_if_reject">
+
+<dt> <b>warn_if_reject</b> (Postfix versions 20011119 and later)
+<dd> Change the meaning of the next restriction, so that it logs
+a warning instead of rejecting a request (look for logfile records
+that contain "reject_warning").  This is useful for testing new
+restrictions in a "live" environment without risking unnecessary
+loss of mail.
+
+<p>
+
 <a name="reject_unauth_pipelining">
 
 <dt> <b>reject_unauth_pipelining</b> <dd> Reject the request when
index 3af78864a2599ba8cec80e014aef7c871c23ad3a..a3f3571b5d1d26a558989968b5d243c534065c9c 100644 (file)
@@ -73,9 +73,10 @@ VIRTUAL(8)                                             VIRTUAL(8)
        <b>tual</b><i>_</i><b>owner</b><i>_</i><b>maps</b> or <b>virtual</b><i>_</i><b>uid</b><i>_</i><b>maps</b>.
 
 <b>SECURITY</b>
-       The virtual delivery agent is not security sensitive, provided
-       that the lookup tables with recipient information are adequately
-       protected. This program is not designed to run chrooted.
+       The virtual delivery agent is not security sensitive, pro-
+       vided  that the lookup tables with recipient user/group ID
+       information are adequately protected. This program is  not
+       designed to run chrooted.
 
 <b>STANDARDS</b>
        <a href="http://www.faqs.org/rfcs/rfc822.html">RFC 822</a> (ARPA Internet Text Messages)
@@ -85,120 +86,120 @@ VIRTUAL(8)                                             VIRTUAL(8)
        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 <b>syslogd</b>(8).  Cor-
-       rupted message files are marked so that the queue  manager
+       Problems and transactions are logged to <b>syslogd</b>(8).   Cor-
+       rupted  message files are marked so that the queue manager
        can move them to the <b>corrupt</b> queue afterwards.
 
-       Depending  on the setting of the <b>notify</b><i>_</i><b>classes</b> parameter,
-       the postmaster is notified of bounces and of  other  trou-
+       Depending on the setting of the <b>notify</b><i>_</i><b>classes</b>  parameter,
+       the  postmaster  is notified of bounces and of other trou-
        ble.
 
 <b>BUGS</b>
        This delivery agent silently ignores address extensions.
 
        Postfix should have lookup tables that can return multiple
-       result attributes. In order to avoid the inconvenience  of
+       result  attributes. In order to avoid the inconvenience of
        maintaining three tables, use an LDAP or MYSQL database.
 
 <b>CONFIGURATION</b> <b>PARAMETERS</b>
-       The  following  <b>main.cf</b> parameters are especially relevant
-       to this program. See the Postfix <b>main.cf</b> file  for  syntax
-       details  and  for  default  values. Use the <b>postfix</b> <b>reload</b>
+       The following <b>main.cf</b> parameters are  especially  relevant
+       to  this  program. See the Postfix <b>main.cf</b> file for syntax
+       details and for default values.  Use  the  <b>postfix</b>  <b>reload</b>
        command after a configuration change.
 
 <b>Mailbox</b> <b>delivery</b>
        <b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>base</b>
-              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  <b>virtual</b><i>_</i><b>mail-</b>
-              <b>box</b><i>_</i><b>maps</b>  doesn't  litter the filesystem with mail-
-              boxes.  While it could be set to "/", this  setting
+              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 <b>virtual</b><i>_</i><b>mail-</b>
+              <b>box</b><i>_</i><b>maps</b> doesn't litter the filesystem  with  mail-
+              boxes.   While it could be set to "/", this setting
               isn't recommended.
 
        <b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>maps</b> (regexp maps disallowed)
               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
+              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 UNIX-style mailbox file.
 
-              Note  that  <b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>base</b> is unconditionally
+              Note that <b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>base</b>  is  unconditionally
               prepended to this path.
 
        <b>virtual</b><i>_</i><b>minimum</b><i>_</i><b>uid</b>
-              Specifies a minimum uid that will be accepted as  a
-              return    from   a   <b>virtual</b><i>_</i><b>owner</b><i>_</i><b>maps</b>   or   <b>vir-</b>
-              <b>tual</b><i>_</i><b>uid</b><i>_</i><b>maps</b> lookup.  Returned  values  less  than
-              this  will  be  rejected,  and  the message will be
+              Specifies  a minimum uid that will be accepted as a
+              return   from   a   <b>virtual</b><i>_</i><b>owner</b><i>_</i><b>maps</b>   or    <b>vir-</b>
+              <b>tual</b><i>_</i><b>uid</b><i>_</i><b>maps</b>  lookup.   Returned  values less than
+              this will be rejected,  and  the  message  will  be
               deferred.
 
        <b>virtual</b><i>_</i><b>uid</b><i>_</i><b>maps</b> (regexp maps disallowed)
               Recipients are looked up in these maps to determine
-              the  user  ID to be used when writing to the target
+              the user ID to be used when writing to  the  target
               mailbox.
 
        <b>virtual</b><i>_</i><b>gid</b><i>_</i><b>maps</b> (regexp maps disallowed)
               Recipients are looked up in these maps to determine
-              the  group ID to be used when writing to the target
+              the group ID to be used when writing to the  target
               mailbox.
 
 <b>Locking</b> <b>controls</b>
        <b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>lock</b>
-              How to lock UNIX-style mailboxes: one  or  more  of
-              <b>flock</b>,   <b>fcntl</b>   or  <b>dotlock</b>.  The  <b>dotlock</b>  method
-              requires that the recipient UID or  GID  has  write
+              How  to  lock  UNIX-style mailboxes: one or more of
+              <b>flock</b>,  <b>fcntl</b>  or  <b>dotlock</b>.  The   <b>dotlock</b>   method
+              requires  that  the  recipient UID or GID has write
               access to the parent directory of the mailbox file.
 
-              This setting is ignored with <b>maildir</b>  style  deliv-
+              This  setting  is ignored with <b>maildir</b> style deliv-
               ery,  because  such  deliveries  are  safe  without
               explicit locks.
 
-              Use the command <b>postconf</b> <b>-m</b> to find out what  lock-
+              Use  the command <b>postconf</b> <b>-l</b> to find out what lock-
               ing methods are available on your system.
 
        <b>deliver</b><i>_</i><b>lock</b><i>_</i><b>attempts</b>
-              Limit  the  number of attempts to acquire an exclu-
+              Limit the number of attempts to acquire  an  exclu-
               sive lock on a UNIX-style mailbox file.
 
        <b>deliver</b><i>_</i><b>lock</b><i>_</i><b>delay</b>
               Time (default: seconds) between successive attempts
-              to  acquire an exclusive lock on a UNIX-style mail-
-              box file. The actual delay is slightly  randomized.
+              to acquire an exclusive lock on a UNIX-style  mail-
+              box  file. The actual delay is slightly randomized.
 
        <b>stale</b><i>_</i><b>lock</b><i>_</i><b>time</b>
-              Limit  the  time  after  which  a stale lockfile is
-              removed (applicable to UNIX-style mailboxes  only).
+              Limit the time after  which  a  stale  lockfile  is
+              removed  (applicable to UNIX-style mailboxes only).
 
 <b>Resource</b> <b>controls</b>
        <b>virtual</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
               Limit the number of parallel deliveries to the same
               domain via the <b>virtual</b> delivery agent.  The default
               limit is taken from the <b>default</b><i>_</i><b>destination</b><i>_</i><b>concur-</b>
-              <b>rency</b><i>_</i><b>limit</b> parameter.  The limit  is  enforced  by
+              <b>rency</b><i>_</i><b>limit</b>  parameter.   The  limit is enforced by
               the Postfix queue manager.
 
        <b>virtual</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
               Limit the number of recipients per message delivery
-              via the <b>virtual</b> delivery agent.  The default  limit
-              is   taken   from  the  <b>default</b><i>_</i><b>destination</b><i>_</i><b>recipi-</b>
-              <b>ent</b><i>_</i><b>limit</b> parameter.  The limit is enforced by  the
+              via  the <b>virtual</b> delivery agent.  The default limit
+              is  taken  from   the   <b>default</b><i>_</i><b>destination</b><i>_</i><b>recipi-</b>
+              <b>ent</b><i>_</i><b>limit</b>  parameter.  The limit is enforced by the
               Postfix queue manager.
 
        <b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>limit</b>
-              The  maximal  size in bytes of a mailbox or maildir
+              The maximal size in bytes of a mailbox  or  maildir
               file.  Set to zero to disable the limit.
 
 <b>HISTORY</b>
-       This agent was  originally  based  on  the  Postfix  local
+       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
+       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 <b>Delivered-To:</b> header appears in the  <b>qmail</b>  system  by
+       The  <b>Delivered-To:</b>  header  appears in the <b>qmail</b> system by
        Daniel Bernstein.
 
-       The  <b>maildir</b>  structure  appears  in  the  <b>qmail</b> system by
+       The <b>maildir</b> structure  appears  in  the  <b>qmail</b>  system  by
        Daniel Bernstein.
 
 <b>SEE</b> <b>ALSO</b>
@@ -207,7 +208,7 @@ VIRTUAL(8)                                             VIRTUAL(8)
        <a href="qmgr.8.html">qmgr(8)</a> queue manager
 
 <b>LICENSE</b>
-       The Secure Mailer license must be  distributed  with  this
+       The  Secure  Mailer  license must be distributed with this
        software.
 
 <b>AUTHOR(S)</b>
index 083f99f4b34efff7abc45ce18031d57808fbed2b..2c9a7f27eced8019eb4f8fe772a07b066a516e52 100644 (file)
@@ -230,7 +230,7 @@ ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543
                RANLIB=echo
                SYSLIBS="-lresolv -lsocket -lnsl"
                ;;
-Rhapsody.5*|Darwin.1.*)
+Rhapsody.5*|Darwin.*)
                SYSTYPE=RHAPSODY5
                # Use the native compiler by default
                : ${CC=cc}
index 386d763f37a0710c92116b322972a419ecec3053..d45ec5ba48bcf06f99d8015cb5483669cd0e174c 100644 (file)
@@ -150,6 +150,10 @@ The following \fBmain.cf\fR parameters are especially relevant to
 this topic. See the Postfix \fBmain.cf\fR file for syntax details
 and for default values. Use the \fBpostfix reload\fR command after
 a configuration change.
+.IP "\fBparent_domain_matches_subdomains\fR (versions >= 20011119)"
+List of Postfix features that use \fIdomain.name\fR patterns
+to match \fIsub.domain.name\fR (as opposed to
+requiring \fI.domain.name\fR patterns).
 .IP \fBtransport_maps\fR
 List of transport lookup tables.
 .PP
index f11f4854b5ef02d845ca28180d60c77599899736..49d6eca37c0d29ce4057fc9827b5a20ff4e3918b 100644 (file)
@@ -126,6 +126,10 @@ a send request for the corresponding destination.
 .IP \fBfast_flush_purge_time\fR
 Remove an empty "fast flush" logfile that was not updated in
 this amount of time (default time unit: days).
+.IP "\fBparent_domain_matches_subdomains\fR (versions >= 20011119)"
+List of Postfix features that use \fIdomain.name\fR patterns
+to match \fIsub.domain.name\fR (as opposed to
+requiring \fI.domain.name\fR patterns).
 .SH SEE ALSO
 .na
 .nf
index 182338e7fe33df0ae119151570766d5e267e0b50..edad7fd82fbf45ba3717d9cdf7d9f4f2ed265461 100644 (file)
@@ -183,6 +183,10 @@ it is penalized with tarpit delays.
 .SH "UCE control restrictions"
 .ad
 .fi
+.IP "\fBparent_domain_matches_subdomains\fR (versions >= 20011119)"
+List of Postfix features that use \fIdomain.name\fR patterns
+to match \fIsub.domain.name\fR (as opposed to
+requiring \fI.domain.name\fR patterns).
 .IP \fBsmtpd_client_restrictions\fR
 Restrict what clients may connect to this mail system.
 .IP \fBsmtpd_helo_required\fR
index bf110a70261e57bf44607655f81ab59e5a65b511..410b72a3b37be927aea8d51206fa56f536536245 100644 (file)
@@ -108,6 +108,10 @@ The default transport is \fBsmtp\fR.
 .sp
 Syntax is \fItransport\fR:\fInexthop\fR; see \fBtransport\fR(5)
 for details. The :\fInexthop\fR part is optional.
+.IP "\fBparent_domain_matches_subdomains\fR (versions >= 20011119)"
+List of Postfix features that use \fIdomain.name\fR patterns
+to match \fIsub.domain.name\fR (as opposed to
+requiring \fI.domain.name\fR patterns).
 .IP \fBrelayhost\fR
 The default host to send non-local mail to when no entry is matched
 in the \fBtransport\fR(5) table.
index 52b1fbe7508beda19f488fb7b4dfc9d224c513b5..b76c1a75241fa92813f4a3738b974183e44b6ab2 100644 (file)
@@ -86,9 +86,11 @@ numerical user ID values that may be specified in any
 .SH SECURITY
 .na
 .nf
+.ad
+.fi
 The virtual delivery agent is not security sensitive, provided
-that the lookup tables with recipient information are adequately
-protected. This program is not designed to run chrooted.
+that the lookup tables with recipient user/group ID information are
+adequately protected. This program is not designed to run chrooted.
 .SH STANDARDS
 .na
 .nf
@@ -162,7 +164,7 @@ directory of the mailbox file.
 This setting is ignored with \fBmaildir\fR style delivery,
 because such deliveries are safe without explicit locks.
 
-Use the command \fBpostconf -m\fR to find out what locking methods
+Use the command \fBpostconf -l\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
index 70c1a584375fad18eacc95718011dda29a8e181f..ff2c109d1f428d3ccdca2c00c1ce002627655eb1 100644 (file)
 #      this topic. See the Postfix \fBmain.cf\fR file for syntax details
 #      and for default values. Use the \fBpostfix reload\fR command after
 #      a configuration change.
+# .IP "\fBparent_domain_matches_subdomains\fR (versions >= 20011119)"
+#      List of Postfix features that use \fIdomain.name\fR patterns
+#      to match \fIsub.domain.name\fR (as opposed to
+#      requiring \fI.domain.name\fR patterns).
 # .IP \fBtransport_maps\fR
 #      List of transport lookup tables.
 # .PP
index fc0819df193a1bf7d19087cf38367e3e08556665..835aea3787e67ed236f3c85950ea6683ca05ef5e 100644 (file)
@@ -78,4 +78,7 @@ flush.o: ../../include/mail_conf.h
 flush.o: ../../include/mail_scan_dir.h
 flush.o: ../../include/maps.h
 flush.o: ../../include/domain_list.h
+flush.o: ../../include/match_list.h
+flush.o: ../../include/match_ops.h
+flush.o: ../../include/match_parent_style.h
 flush.o: ../../include/mail_server.h
index 67a8814c85616dd469000675f64f817b88267b52..71258a1a42c8b92be7ed6522d8c87ffe0f02f640 100644 (file)
 /* .IP \fBfast_flush_purge_time\fR
 /*     Remove an empty "fast flush" logfile that was not updated in
 /*     this amount of time (default time unit: days).
+/* .IP "\fBparent_domain_matches_subdomains\fR (versions >= 20011119)"
+/*     List of Postfix features that use \fIdomain.name\fR patterns
+/*     to match \fIsub.domain.name\fR (as opposed to
+/*     requiring \fI.domain.name\fR patterns).
 /* SEE ALSO
 /*     smtpd(8) Postfix SMTP server
 /*     qmgr(8) Postfix queue manager
 #include <mail_scan_dir.h>
 #include <maps.h>
 #include <domain_list.h>
+#include <match_parent_style.h>
 
 /* Single server skeleton. */
 
@@ -636,7 +641,8 @@ static void flush_service(VSTREAM *client_stream, char *unused_service,
 
 static void pre_jail_init(char *unused_name, char **unused_argv)
 {
-    flush_domains = domain_list_init(var_fflush_domains);
+    flush_domains = domain_list_init(match_parent_style(VAR_FFLUSH_DOMAINS),
+                                    var_fflush_domains);
 }
 
 /* main - pass control to the single-threaded skeleton */
index c7548ebd17945b803f3ae62aa414b76fe379d14e..92773fe6820fcb85d8e49ec0f33189aa9edee489 100644 (file)
@@ -19,7 +19,7 @@ SRCS  = been_here.c bounce.c canon_addr.c cleanup_strerror.c clnt_stream.c \
        timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \
        tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \
        flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c \
-       verp_sender.c
+       verp_sender.c match_parent_style.c
 OBJS   = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
        debug_peer.o debug_process.o defer.o deliver_completed.o \
        deliver_flock.o deliver_pass.o deliver_request.o domain_list.o \
@@ -40,7 +40,7 @@ OBJS  = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \
        timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \
        tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \
        flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o \
-       verp_sender.o
+       verp_sender.o match_parent_style.o
 HDRS   = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
        config.h debug_peer.h debug_process.h defer.h deliver_completed.h \
        deliver_flock.h deliver_pass.h deliver_request.h domain_list.h \
@@ -56,7 +56,8 @@ HDRS  = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \
        recipient_list.h record.h resolve_clnt.h resolve_local.h \
        rewrite_clnt.h sent.h smtp_stream.h split_addr.h string_list.h \
        sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h \
-       mbox_conf.h mbox_open.h abounce.h qmqp_proto.h verp_sender.h
+       mbox_conf.h mbox_open.h abounce.h qmqp_proto.h verp_sender.h \
+       match_parent_style.h
 TESTSRC        = rec2stream.c stream2rec.c recdump.c
 WARN   = -W -Wformat -Wimplicit -Wmissing-prototypes \
        -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
@@ -318,7 +319,10 @@ debug_peer.o: ../../include/sys_defs.h
 debug_peer.o: ../../include/msg.h
 debug_peer.o: mail_params.h
 debug_peer.o: namadr_list.h
+debug_peer.o: ../../include/match_list.h
+debug_peer.o: ../../include/match_ops.h
 debug_peer.o: debug_peer.h
+debug_peer.o: match_parent_style.h
 debug_process.o: debug_process.c
 debug_process.o: ../../include/sys_defs.h
 debug_process.o: ../../include/msg.h
@@ -388,8 +392,8 @@ deliver_request.o: deliver_request.h
 domain_list.o: domain_list.c
 domain_list.o: ../../include/sys_defs.h
 domain_list.o: ../../include/match_list.h
-domain_list.o: ../../include/match_ops.h
 domain_list.o: domain_list.h
+domain_list.o: ../../include/match_ops.h
 dot_lockfile.o: dot_lockfile.c
 dot_lockfile.o: ../../include/sys_defs.h
 dot_lockfile.o: ../../include/vstring.h
@@ -721,6 +725,13 @@ mark_corrupt.o: ../../include/vbuf.h
 mark_corrupt.o: mail_queue.h
 mark_corrupt.o: ../../include/vstring.h
 mark_corrupt.o: mark_corrupt.h
+match_parent_style.o: match_parent_style.c
+match_parent_style.o: ../../include/sys_defs.h
+match_parent_style.o: string_list.h
+match_parent_style.o: ../../include/match_list.h
+match_parent_style.o: ../../include/match_ops.h
+match_parent_style.o: mail_params.h
+match_parent_style.o: match_parent_style.h
 mbox_conf.o: mbox_conf.c
 mbox_conf.o: ../../include/sys_defs.h
 mbox_conf.o: ../../include/name_mask.h
@@ -799,8 +810,8 @@ mypwd.o: mypwd.h
 namadr_list.o: namadr_list.c
 namadr_list.o: ../../include/sys_defs.h
 namadr_list.o: ../../include/match_list.h
-namadr_list.o: ../../include/match_ops.h
 namadr_list.o: namadr_list.h
+namadr_list.o: ../../include/match_ops.h
 off_cvt.o: off_cvt.c
 off_cvt.o: ../../include/sys_defs.h
 off_cvt.o: ../../include/msg.h
@@ -935,9 +946,12 @@ resolve_local.o: ../../include/sys_defs.h
 resolve_local.o: ../../include/msg.h
 resolve_local.o: ../../include/mymalloc.h
 resolve_local.o: string_list.h
+resolve_local.o: ../../include/match_list.h
+resolve_local.o: ../../include/match_ops.h
 resolve_local.o: mail_params.h
 resolve_local.o: own_inet_addr.h
 resolve_local.o: resolve_local.h
+resolve_local.o: match_parent_style.h
 rewrite_clnt.o: rewrite_clnt.c
 rewrite_clnt.o: ../../include/sys_defs.h
 rewrite_clnt.o: ../../include/msg.h
@@ -985,8 +999,8 @@ stream2rec.o: rec_type.h
 string_list.o: string_list.c
 string_list.o: ../../include/sys_defs.h
 string_list.o: ../../include/match_list.h
-string_list.o: ../../include/match_ops.h
 string_list.o: string_list.h
+string_list.o: ../../include/match_ops.h
 sys_exits.o: sys_exits.c
 sys_exits.o: ../../include/sys_defs.h
 sys_exits.o: ../../include/msg.h
index 29170bad58f7f9ebefa806cf669ecbdf515e7386..c7096c97321938e7f62e6a063b20286dc09aad0a 100644 (file)
@@ -69,6 +69,7 @@
 #include <mail_params.h>
 #include <namadr_list.h>
 #include <debug_peer.h>
+#include <match_parent_style.h>
 
 /* Application-specific. */
 
@@ -97,7 +98,9 @@ void    debug_peer_init(void)
      * Finally.
      */
     if (*var_debug_peer_list)
-       debug_peer_list = namadr_list_init(var_debug_peer_list);
+       debug_peer_list =
+           namadr_list_init(match_parent_style(VAR_DEBUG_PEER_LIST),
+                            var_debug_peer_list);
 }
 
 /* debug_peer_check - see if this peer needs verbose logging */
index cf4a614c2b44dcce6959653687e75a8ee44bff03..f428d551ebf99776e30065d0d1cc758640bfeec5 100644 (file)
@@ -97,14 +97,14 @@ static int deliver_pass_send_request(VSTREAM *stream, DELIVER_REQUEST *request,
               ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, request->flags,
               ATTR_TYPE_STR, MAIL_ATTR_QUEUE, request->queue_name,
               ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, request->queue_id,
-              ATTR_TYPE_NUM, MAIL_ATTR_OFFSET, request->data_offset,
-              ATTR_TYPE_NUM, MAIL_ATTR_SIZE, request->data_size,
+              ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, request->data_offset,
+              ATTR_TYPE_LONG, MAIL_ATTR_SIZE, request->data_size,
               ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, nexthop,
               ATTR_TYPE_STR, MAIL_ATTR_SENDER, request->sender,
               ATTR_TYPE_STR, MAIL_ATTR_ERRTO, request->errors_to,
               ATTR_TYPE_STR, MAIL_ATTR_RRCPT, request->return_receipt,
-              ATTR_TYPE_NUM, MAIL_ATTR_TIME, request->arrival_time,
-              ATTR_TYPE_NUM, MAIL_ATTR_OFFSET, offs,
+              ATTR_TYPE_LONG, MAIL_ATTR_TIME, request->arrival_time,
+              ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, offs,
               ATTR_TYPE_STR, MAIL_ATTR_RECIP, addr,
               ATTR_TYPE_NUM, MAIL_ATTR_OFFSET, 0,
               ATTR_TYPE_END);
index 344276a1d4c0ac621378f66ef2cfa0aa2c98231f..35c83e78061852536bab5475a795792a4929a8af 100644 (file)
@@ -196,13 +196,13 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
                  ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &request->flags,
                  ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue_name,
                  ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
-                 ATTR_TYPE_NUM, MAIL_ATTR_OFFSET, &request->data_offset,
-                 ATTR_TYPE_NUM, MAIL_ATTR_SIZE, &request->data_size,
+                 ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, &request->data_offset,
+                 ATTR_TYPE_LONG, MAIL_ATTR_SIZE, &request->data_size,
                  ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, nexthop,
                  ATTR_TYPE_STR, MAIL_ATTR_SENDER, address,
                  ATTR_TYPE_STR, MAIL_ATTR_ERRTO, errors_to,
                  ATTR_TYPE_STR, MAIL_ATTR_RRCPT, return_receipt,
-                 ATTR_TYPE_NUM, MAIL_ATTR_TIME, &request->arrival_time,
+                 ATTR_TYPE_LONG, MAIL_ATTR_TIME, &request->arrival_time,
                  ATTR_TYPE_END) != 10)
        return (-1);
     if (mail_open_ok(vstring_str(queue_name),
@@ -222,7 +222,7 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
      */
     for (;;) {
        if (attr_scan(stream, ATTR_FLAG_MORE | ATTR_FLAG_STRICT,
-                     ATTR_TYPE_NUM, MAIL_ATTR_OFFSET, &offset,
+                     ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, &offset,
                      ATTR_TYPE_END) != 1)
            return (-1);
        if (offset == 0)
index 1322642d0f9df374d307f93553cd75dc710244ee..d4ea536b29f27516598b01ac0b2930f1f5f63b0b 100644 (file)
@@ -6,7 +6,8 @@
 /* SYNOPSIS
 /*     #include <domain_list.h>
 /*
-/*     DOMAIN_LIST *domain_list_init(pattern_list)
+/*     DOMAIN_LIST *domain_list_init(flags, pattern_list)
+/*     int     flags;
 /*     const char *pattern_list;
 /*
 /*     int     domain_list_match(list, name)
@@ -16,6 +17,8 @@
 /*     void domain_list_free(list)
 /*     DOMAIN_LIST *list;
 /* DESCRIPTION
+/*     This is a convenience wrapper around the match_list module.
+/*
 /*     This module implements tests for list membership of a host or
 /*     domain name.
 /*
 /*     insensitive. In order to reverse the result, precede a non-file
 /*     name pattern with an exclamation point (!).
 /*
-/*     domain_list_init() performs initializations. The argument is a
-/*     list of domain patterns, or the name of a file containing domain
-/*     patterns.
+/*     domain_list_init() performs initializations. The first argument
+/*     is the bit-wise OR of zero or more of the following:
+/* .RS
+/* .IP MATCH_FLAG_PARENT
+/*      The hostname pattern foo.com matches itself and any name below
+/*      the domain foo.com. If this flag is cleared, foo.com matches itself 
+/*     only, and .foo.com matches any name below the domain foo.com.
+/* .RE
+/*     Specify MATCH_FLAG_NONE to request none of the above.
+/*     The second argument is a list of domain patterns, or the name of
+/*     a file containing domain patterns.
 /*
 /*     domain_list_match() matches the specified host or domain name
 /*     against the specified pattern list.
 /* Utility library. */
 
 #include <match_list.h>
-#include <match_ops.h>
 
 /* Global library. */
 
 #include "domain_list.h"
 
-/* domain_list_init - initialize domain list */
-
-DOMAIN_LIST *domain_list_init(const char *patterns)
-{
-    return (match_list_init(patterns, 1, match_hostname));
-}
-
-/* domain_list_match - match host against domain list */
-
-int     domain_list_match(DOMAIN_LIST *list, const char *name)
-{
-    return (match_list_match(list, name));
-}
-
-/* domain_list_free - release storage */
-
-void    domain_list_free(DOMAIN_LIST *list)
-{
-    match_list_free(list);
-}
-
 #ifdef TEST
 
 #include <msg.h>
@@ -120,7 +109,7 @@ main(int argc, char **argv)
     }
     if (argc != optind + 2)
        usage(argv[0]);
-    list = domain_list_init(argv[optind]);
+    list = domain_list_init(MATCH_FLAG_PARENT, argv[optind]);
     host = argv[optind + 1];
     vstream_printf("%s: %s\n", host, domain_list_match(list, host) ?
                   "YES" : "NO");
index b36f516b444f89b6188c5aae994afecc25c97fe9..23f60c78950a1693adb9f8f021a82f8d3bc1a3f1 100644 (file)
 /* DESCRIPTION
 /* .nf
 
+ /*
+  * Utility library.
+  */
+#include <match_list.h>
+#include <match_ops.h>
+
  /*
   * External interface.
   */
-typedef struct MATCH_LIST DOMAIN_LIST;
+#define DOMAIN_LIST    MATCH_LIST
 
-extern DOMAIN_LIST *domain_list_init(const char *);
-extern int domain_list_match(DOMAIN_LIST *, const char *);
-extern void domain_list_free(DOMAIN_LIST *);
+#define domain_list_init(f, p) match_list_init((f), (p), 1, match_hostname)
+#define domain_list_match      match_list_match
+#define domain_list_free       match_list_free
 
 /* LICENSE
 /* .ad
index 98da1b2d755c5995e951ba07cf0336dc2aed6816..803996ffc7421a50c54407cbc552a55802baa254 100644 (file)
@@ -64,6 +64,7 @@
 /*     char    *var_mynetworks_style;
 /*     char    *var_verp_delims;
 /*     char    *var_verp_filter;
+/*     char    *var_par_dom_match;
 /*
 /*     char    *var_import_environ;
 /*     char    *var_export_environ;
@@ -187,6 +188,7 @@ char   *var_mynetworks_style;
 char   *var_verp_delims;
 char   *var_verp_filter;
 int     var_in_flow_delay;
+char   *var_par_dom_match;
 
 char   *var_import_environ;
 char   *var_export_environ;
@@ -312,6 +314,7 @@ void    mail_params_init()
        VAR_DEBUG_PEER_LIST, DEF_DEBUG_PEER_LIST, &var_debug_peer_list, 0, 0,
        VAR_VERP_DELIMS, DEF_VERP_DELIMS, &var_verp_delims, 2, 2,
        VAR_VERP_FILTER, DEF_VERP_FILTER, &var_verp_filter, 1, 0,
+       VAR_PAR_DOM_MATCH, DEF_PAR_DOM_MATCH, &var_par_dom_match, 0, 0,
        0,
     };
     static CONFIG_STR_FN_TABLE function_str_defaults_2[] = {
index 21b8ef1850607b59a8e211808f552649179a4caa..c65cee5eeaa3c4102fabbf9856ecc6249e3ce2e9 100644 (file)
@@ -1140,6 +1140,8 @@ extern int var_access_map_code;
 #define CHECK_RECIP_ACL                "check_recipient_access"
 #define CHECK_ETRN_ACL         "check_etrn_access"
 
+#define WARN_IF_REJECT         "warn_if_reject"
+
 #define REJECT_MAPS_RBL                "reject_maps_rbl"
 #define VAR_MAPS_RBL_CODE      "maps_rbl_reject_code"
 #define DEF_MAPS_RBL_CODE      554
@@ -1319,6 +1321,21 @@ extern bool var_verp_bounce_off;
 #define DEF_IN_FLOW_DELAY                      "1s"
 extern int var_in_flow_delay;
 
+ /*
+  * Backwards compatibility: foo.com matches itself and names below foo.com.
+  */
+#define VAR_PAR_DOM_MATCH              "parent_domain_matches_subdomains"
+#define DEF_PAR_DOM_MATCH              VAR_DEBUG_PEER_LIST "," \
+                                       VAR_FFLUSH_DOMAINS "," \
+                                       VAR_MYNETWORKS "," \
+                                       VAR_PERM_MX_NETWORKS "," \
+                                       VAR_QMQPD_CLIENTS "," \
+                                       VAR_RELAY_DOMAINS "," \
+                                       SMTPD_ACCESS_MAPS
+extern char *var_par_dom_match;
+
+#define SMTPD_ACCESS_MAPS              "smtpd_access_maps"
+
 /* LICENSE
 /* .ad
 /* .fi
index 9ee1b16fefd0ddd350ca582a53e6b1876aa9b61e..8d16673aac65eaaeafcaa245dc96aea9c3200202 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Snapshot-20011120"
+#define DEF_MAIL_VERSION       "Snapshot-20011121"
 extern char *var_mail_version;
 
 /* LICENSE
diff --git a/postfix/src/global/match_parent_style.c b/postfix/src/global/match_parent_style.c
new file mode 100644 (file)
index 0000000..a914f61
--- /dev/null
@@ -0,0 +1,72 @@
+/*++
+/* NAME
+/*     match_parent_style 3
+/* SUMMARY
+/*     parent domain matching control
+/* SYNOPSIS
+/*     #include <match_parent_style.h>
+/*
+/*     int     match_parent_style(name)
+/*     const char *name;
+/* DESCRIPTION
+/*     This module queries configuration parameters for the policy that
+/*     controls how wild-card parent domain names are used by various
+/*     postfix lookup mechanisms.
+/*
+/*     match_parent_style() looks up "name" in the
+/*      parent_domain_matches_subdomain configuration parameter
+/*     and returns either MATCH_FLAG_PARENT or MATCH_PARENT_NONE.
+/* DIAGNOSTICS
+/*     Fatal error: out of memory, name listed under both parent wild card
+/*     matching policies.
+/* SEE ALSO
+/*     string_list(3) plain string matching
+/*     domain_list(3) match host name patterns
+/*     namadr_list(3) match host name/address patterns
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+/* Global library. */
+
+#include <string_list.h>
+#include <mail_params.h>
+#include <match_parent_style.h>
+
+/* Application-specific. */
+
+static STRING_LIST *match_par_dom_list;
+
+int     match_parent_style(const char *name)
+{
+    int     result;
+
+    /*
+     * Initialize on the fly.
+     */
+    if (match_par_dom_list == 0) 
+       match_par_dom_list =
+           string_list_init(MATCH_FLAG_NONE, var_par_dom_match);
+
+    /*
+     * Look up the parent domain matching policy.
+     */
+    if (string_list_match(match_par_dom_list, name))
+       result = MATCH_FLAG_PARENT;
+    else
+       result = 0;
+    return (result);
+}
diff --git a/postfix/src/global/match_parent_style.h b/postfix/src/global/match_parent_style.h
new file mode 100644 (file)
index 0000000..7b51edd
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _MATCH_PARENT_STYLE_H_INCLUDED_
+#define _MATCH_PARENT_STYLE_H_INCLUDED_
+
+/*++
+/* NAME
+/*     match_parent_style 3h
+/* SUMMARY
+/*     parent domain matching control
+/* SYNOPSIS
+/*     #include <match_parent_style.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <match_ops.h>
+
+ /*
+  * External interface.
+  */
+extern int match_parent_style(const char *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif
index 0e6b1bba7304a20bcc91900c3121c11268c0d30b..c5169d87e59fb5b852d398e99a94d3d0e9422567 100644 (file)
@@ -6,7 +6,8 @@
 /* SYNOPSIS
 /*     #include <namadr_list.h>
 /*
-/*     NAMADR_LIST *namadr_list_init(pattern_list)
+/*     NAMADR_LIST *namadr_list_init(flags, pattern_list)
+/*     int     flags;
 /*     const char *pattern_list;
 /*
 /*     int     namadr_list_match(list, name, addr)
@@ -17,6 +18,8 @@
 /*     void    namadr_list_free(list)
 /*     NAMADR_LIST *list;
 /* DESCRIPTION
+/*     This is a convenience wrapper around the match_list module.
+/*
 /*     This module implements tests for list membership of a
 /*     hostname or network address.
 /*
 /*     a pattern, or when any of its parent domains matches a
 /*     pattern. The matching process is case insensitive.
 /*
-/*     namadr_list_init() performs initializations. The argument
-/*     is a list of patterns, or the absolute pathname of a file
-/*     with patterns.
+/*     namadr_list_init() performs initializations. The first
+/*     argument is the bit-wise OR of zero or more of the
+/*     following:
+/* .RS
+/* .IP MATCH_FLAG_PARENT
+/*     The hostname pattern foo.com matches itself and any name below
+/*     the domain foo.com. If this flag is cleared, foo.com matches itself
+/*     only, and .foo.com matches any name below the domain foo.com.
+/* .RE
+/*     Specify MATCH_FLAG_NONE to request none of the above.
+/*     The second argument is a list of patterns, or the absolute
+/*     pathname of a file with patterns.
 /*
 /*     namadr_list_match() matches the specified host name and
 /*     address against the specified list of patterns.
 /* Utility library. */
 
 #include <match_list.h>
-#include <match_ops.h>
 
 /* Global library. */
 
 #include "namadr_list.h"
 
-/* namadr_list_init - initialize domain list */
-
-NAMADR_LIST *namadr_list_init(const char *patterns)
-{
-    return (match_list_init(patterns, 2, match_hostaddr, match_hostname));
-}
-
-/* namadr_list_match - match host against set of namadr_list patterns */
-
-int     namadr_list_match(NAMADR_LIST *list, const char *name, const char *addr)
-{
-    return (match_list_match(list, addr, name));
-}
-
-/* namadr_list_free - release storage */
-
-void    namadr_list_free(NAMADR_LIST *list)
-{
-    match_list_free(list);
-}
-
 #ifdef TEST
 
 #include <msg.h>
@@ -126,7 +116,7 @@ main(int argc, char **argv)
     }
     if (argc != optind + 3)
        usage(argv[0]);
-    list = namadr_list_init(argv[optind]);
+    list = namadr_list_init(MATCH_FLAG_PARENT, argv[optind]);
     host = argv[optind + 1];
     addr = argv[optind + 2];
     vstream_printf("%s/%s: %s\n", host, addr,
index 186cd66c1b7931fb206c2dd9aed51f35718ee23a..9bf90d7684d5866e0d395d858ee079279a3176fe 100644 (file)
@@ -7,18 +7,25 @@
 /* SUMMARY
 /*     name/address membership
 /* SYNOPSIS
-/*     #include <namadr_list_list.h>
+/*     #include <namadr_list.h>
 /* DESCRIPTION
 /* .nf
 
+ /*
+  * Utility library.
+  */
+#include <match_list.h>
+#include <match_ops.h>
+
  /*
   * External interface.
   */
-typedef struct MATCH_LIST NAMADR_LIST;
+#define NAMADR_LIST MATCH_LIST
 
-extern NAMADR_LIST *namadr_list_init(const char *);
-extern int namadr_list_match(NAMADR_LIST *, const char *, const char *);
-extern void namadr_list_free(NAMADR_LIST *);
+#define namadr_list_init(f, p) \
+       match_list_init((f), (p), 2, match_hostname, match_hostaddr)
+#define namadr_list_match      match_list_match
+#define namadr_list_free       match_list_free
 
 /* LICENSE
 /* .ad
index 42fbae7b3fe79e74ac3693ae141e828f25a2a497..94a5a4dbf7708d6436c2248582fff1a556938b5b 100644 (file)
@@ -58,6 +58,7 @@
 #include <mail_params.h>
 #include <own_inet_addr.h>
 #include <resolve_local.h>
+#include <match_parent_style.h>
 
 /* Application-specific */
 
@@ -69,7 +70,7 @@ void    resolve_local_init(void)
 {
     if (resolve_local_list)
        msg_panic("resolve_local_init: duplicate initialization");
-    resolve_local_list = string_list_init(var_mydest);
+    resolve_local_list = string_list_init(MATCH_FLAG_NONE, var_mydest);
 }
 
 /* resolve_local - match address against list of local destinations */
index bcb457e77a73b8270fc7452ffccfdb7e1a92a969..522ff26a1df5c6fda3dab21516fdcf3826fa85f3 100644 (file)
@@ -6,7 +6,8 @@
 /* SYNOPSIS
 /*     #include <string_list.h>
 /*
-/*     STRING_LIST *string_list_init(pattern_list)
+/*     STRING_LIST *string_list_init(flags, pattern_list)
+/*     int     flags;
 /*     const char *pattern_list;
 /*
 /*     int     string_list_match(list, name)
@@ -16,6 +17,8 @@
 /*     void string_list_free(list)
 /*     STRING_LIST *list;
 /* DESCRIPTION
+/*     This is a convenience wrapper around the match_list module.
+/*
 /*     This module implements tests for list membership of a string.
 /*
 /*     Patterns are separated by whitespace and/or commas. A pattern
@@ -28,8 +31,8 @@
 /*     In order to reverse the result, precede a non-file name pattern
 /*     with an exclamation point (!).
 /*
-/*     string_list_init() performs initializations. The argument is a
-/*     list of string patterns.
+/*     string_list_init() performs initializations. The flags argument
+/*     is ignored; pattern_list specifies a list of string patterns.
 /*
 /*     string_list_match() matches the specified string against the
 /*     compiled pattern list.
 /* Utility library. */
 
 #include <match_list.h>
-#include <match_ops.h>
 
 /* Global library. */
 
 #include "string_list.h"
 
-/* string_list_init - initialize string list */
-
-STRING_LIST *string_list_init(const char *patterns)
-{
-    return (match_list_init(patterns, 1, match_string));
-}
-
-/* string_list_match - match string against list */
-
-int     string_list_match(STRING_LIST * list, const char *string)
-{
-    return (match_list_match(list, string));
-}
-
-/* string_list_free - release storage */
-
-void    string_list_free(STRING_LIST * list)
-{
-    match_list_free(list);
-}
-
 #ifdef TEST
 
 #include <msg.h>
@@ -117,7 +98,7 @@ main(int argc, char **argv)
     }
     if (argc != optind + 2)
        usage(argv[0]);
-    list = string_list_init(argv[optind]);
+    list = string_list_init(MATCH_FLAG_NONE, argv[optind]);
     string = argv[optind + 1];
     vstream_printf("%s: %s\n", string, string_list_match(list, string) ?
                   "YES" : "NO");
index 946ecf1d2963d9613ddf4b829cc5e9d605db9a64..daa9541d2f56f1b6ed6bbd11ff811682b85cb0d6 100644 (file)
 /* DESCRIPTION
 /* .nf
 
+ /*
+  * Utility library.
+  */
+#include <match_list.h>
+#include <match_ops.h>
+
  /*
   * External interface.
   */
-typedef struct MATCH_LIST STRING_LIST;
+#define STRING_LIST    MATCH_LIST
 
-extern STRING_LIST *string_list_init(const char *);
-extern int string_list_match(STRING_LIST *, const char *);
-extern void string_list_free(STRING_LIST *);
+#define string_list_init(f, p) match_list_init((f), (p), 1, match_string)
+#define string_list_match      match_list_match
+#define string_list_free       match_list_free
 
 /* LICENSE
 /* .ad
index 29c313c244e09a6651298a4655114acf25ccce8e..cb8f5637fd9dc0330b6b8a219a0489ef93b82aeb 100644 (file)
@@ -176,6 +176,8 @@ 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/match_list.h
+lmtp_sasl_glue.o: ../../include/match_ops.h
 lmtp_sasl_glue.o: ../../include/maps.h
 lmtp_sasl_glue.o: ../../include/dict.h
 lmtp_sasl_glue.o: ../../include/vstream.h
index e3a530ba8a119ed69c45797da004a646ec805a6b..610b1a61d058a1f90eaad0155822b089b6ec5c5a 100644 (file)
@@ -170,7 +170,7 @@ int     deliver_file(LOCAL_STATE state, USER_ATTR usr_attr, char *path)
      * As the mail system, bounce, defer delivery, or report success.
      */
     if (status != 0) {
-       status = (errno == EAGAIN || errno == ENOSPC ?
+       status = (errno == EAGAIN || errno == ENOSPC || errno == ESTALE ?
                  defer_append : bounce_append)
            (BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
             "cannot append message to destination file %s: %s",
index 667a65e1919c633016da96b82ce4d1382679a4d4..a07d1138961fb0b2ea88f78b4ee5eb332a3bf7e5 100644 (file)
@@ -203,7 +203,7 @@ static int deliver_mailbox_file(LOCAL_STATE state, USER_ATTR usr_attr)
      * As the mail system, bounce, defer delivery, or report success.
      */
     if (status != 0) {
-       status = (errno == EAGAIN || errno == ENOSPC ?
+       status = (errno == EAGAIN || errno == ENOSPC || errno == ESTALE ?
                  defer_append : bounce_append)
            (BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
             "cannot access mailbox %s for user %s. %s",
@@ -283,18 +283,14 @@ int     deliver_mailbox(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp)
      */
 #define LAST_CHAR(s) (s[strlen(s) - 1])
 
-    if (*var_mailbox_cmd_maps) {
-       if (cmd_maps == 0)
-           cmd_maps = maps_create(VAR_MAILBOX_CMD_MAPS, var_mailbox_cmd_maps,
-                                  DICT_FLAG_LOCK);
-       if ((map_command = maps_find(cmd_maps, state.msg_attr.user,
-                                DICT_FLAG_FIXED)) != 0) {
-           status = deliver_command(state, usr_attr, map_command);
-       } else {
-           msg_warn("user %s not found in %s",
-                    state.msg_attr.user, var_mailbox_cmd_maps);
-           return (NO);
-       }
+    if (*var_mailbox_cmd_maps && cmd_maps == 0)
+       cmd_maps = maps_create(VAR_MAILBOX_CMD_MAPS, var_mailbox_cmd_maps,
+                              DICT_FLAG_LOCK);
+
+    if (*var_mailbox_cmd_maps
+       && (map_command = maps_find(cmd_maps, state.msg_attr.user,
+                                   DICT_FLAG_FIXED)) != 0) {
+       status = deliver_command(state, usr_attr, map_command);
     } else if (*var_mailbox_command) {
        status = deliver_command(state, usr_attr, var_mailbox_command);
     } else if (*var_home_mailbox && LAST_CHAR(var_home_mailbox) == '/') {
index e9bd0de85c77905c10da88bd7a9f9fccffbb83d2..195e0bfdbed25581557b9bdf7a8bcace719ae84e 100644 (file)
@@ -153,7 +153,8 @@ int     deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr, char *path)
     set_eugid(var_owner_uid, var_owner_gid);
 
     if (status)
-       status = (errno == ENOSPC ? defer_append : bounce_append)
+       status = (errno == ENOSPC || errno == ESTALE ?
+                 defer_append : bounce_append)
            (BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr),
             "maildir delivery failed: %s", vstring_str(why));
     else
index 7dbe299e6e11861c3a823d11508a7fb32d64f1d8..394b267d6a9b758a9feed4499cd9924713ef1165 100644 (file)
@@ -163,19 +163,19 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream)
               ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
               ATTR_TYPE_STR, MAIL_ATTR_QUEUE, message->queue_name,
               ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, message->queue_id,
-              ATTR_TYPE_NUM, MAIL_ATTR_OFFSET, message->data_offset,
-              ATTR_TYPE_NUM, MAIL_ATTR_SIZE, message->data_size,
+              ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, message->data_offset,
+              ATTR_TYPE_LONG, MAIL_ATTR_SIZE, message->data_size,
               ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, nexthop,
               ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
               ATTR_TYPE_STR, MAIL_ATTR_ERRTO, message->errors_to,
               ATTR_TYPE_STR, MAIL_ATTR_RRCPT, message->return_receipt,
-              ATTR_TYPE_NUM, MAIL_ATTR_TIME, message->arrival_time,
+              ATTR_TYPE_LONG, MAIL_ATTR_TIME, message->arrival_time,
               ATTR_TYPE_END);
     if (sender_buf != 0)
        vstring_free(sender_buf);
     for (recipient = list.info; recipient < list.info + list.len; recipient++)
        attr_print(stream, ATTR_FLAG_MORE,
-                  ATTR_TYPE_NUM, MAIL_ATTR_OFFSET, recipient->offset,
+                  ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, recipient->offset,
                   ATTR_TYPE_STR, MAIL_ATTR_RECIP, recipient->address,
                   ATTR_TYPE_END);
     attr_print(stream, ATTR_FLAG_NONE,
index d9559dd9a705cdc29a64e54e5600b460b998dec2..b5cfc89acaa02440b6ee35504083f153ebaf8948 100644 (file)
@@ -23,7 +23,10 @@ $(PROG): $(OBJS) $(LIBS)
 
 ../../conf/main.cf.default: $(PROG) Makefile
        rm -f $@
-       ./$(PROG) -d |egrep -v '^(myhostname|mydomain|mynetworks) ' >$@
+       (echo "# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE"; \
+        echo "# TEXT HERE JUST SHOWS DEFAULT SETTINGS BUILT INTO POSTFIX."; \
+        echo "#"; \
+        ./$(PROG) -d) |egrep -v '^(myhostname|mydomain|mynetworks) ' >$@
 
 Makefile: Makefile.in
        (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
index 403cc8ec5e88894859b94b8a8f4eb9243e78f9ef..45c0a6cdde07d58d458abdc84c56ecc477077051 100644 (file)
@@ -158,19 +158,19 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream)
               ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
               ATTR_TYPE_STR, MAIL_ATTR_QUEUE, message->queue_name,
               ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, message->queue_id,
-              ATTR_TYPE_NUM, MAIL_ATTR_OFFSET, message->data_offset,
-              ATTR_TYPE_NUM, MAIL_ATTR_SIZE, message->data_size,
+              ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, message->data_offset,
+              ATTR_TYPE_LONG, MAIL_ATTR_SIZE, message->data_size,
               ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, nexthop,
               ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
               ATTR_TYPE_STR, MAIL_ATTR_ERRTO, message->errors_to,
               ATTR_TYPE_STR, MAIL_ATTR_RRCPT, message->return_receipt,
-              ATTR_TYPE_NUM, MAIL_ATTR_TIME, message->arrival_time,
+              ATTR_TYPE_LONG, MAIL_ATTR_TIME, message->arrival_time,
               ATTR_TYPE_END);
     if (sender_buf != 0)
        vstring_free(sender_buf);
     for (recipient = list.info; recipient < list.info + list.len; recipient++)
        attr_print(stream, ATTR_FLAG_MORE,
-                  ATTR_TYPE_NUM, MAIL_ATTR_OFFSET, recipient->offset,
+                  ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, recipient->offset,
                   ATTR_TYPE_STR, MAIL_ATTR_RECIP, recipient->address,
                   ATTR_TYPE_END);
     attr_print(stream, ATTR_FLAG_NONE,
index b5fa478cc7ff22c2f96855661bfcf871f246ec41..5e923c5b0711366a0bb6612d84a8cb801a75cc3a 100644 (file)
@@ -89,7 +89,10 @@ qmqpd.o: ../../include/mail_conf.h
 qmqpd.o: ../../include/debug_peer.h
 qmqpd.o: ../../include/mail_stream.h
 qmqpd.o: ../../include/namadr_list.h
+qmqpd.o: ../../include/match_list.h
+qmqpd.o: ../../include/match_ops.h
 qmqpd.o: ../../include/quote_822_local.h
+qmqpd.o: ../../include/match_parent_style.h
 qmqpd.o: ../../include/mail_server.h
 qmqpd.o: qmqpd.h
 qmqpd_peer.o: qmqpd_peer.c
index 5b1d1d1b0d0d6ed85a50c4e2fe7b4b83e797f324..cb23d5a167de915bfea3d906e83b99b2135f6140 100644 (file)
 #include <mail_stream.h>
 #include <namadr_list.h>
 #include <quote_822_local.h>
+#include <match_parent_style.h>
 
 /* Single-threaded server skeleton. */
 
@@ -643,7 +644,9 @@ static void pre_accept(char *unused_name, char **unused_argv)
 static void pre_jail_init(char *unused_name, char **unused_argv)
 {
     debug_peer_init();
-    qmqpd_clients = namadr_list_init(var_qmqpd_clients);
+    qmqpd_clients =
+       namadr_list_init(match_parent_style(VAR_QMQPD_CLIENTS),
+                        var_qmqpd_clients);
 }
 
 /* main - the main program */
index cdf6ad88003e465733e8ace47efb33f227cbbdcd..b23589070d1747a0b6bcfd5514cd4877f6b824b7 100644 (file)
@@ -603,7 +603,7 @@ static void chat(VSTREAM *fp, VSTRING *buf, const char *fmt,...)
 
     smtp_get(buf, fp, var_line_limit);
     if (STR(buf)[0] != '2')
-       msg_fatal("server rejected request: %s", STR(buf));
+       msg_fatal("server rejected ETRN request: %s", STR(buf));
 
     if (msg_verbose)
        msg_info("<<< %s", STR(buf));
index 87ba5ac14eb67689e62a76ee56a27f650be99532..035cd5acab4d95a69c1732cec428c7adfb348f22 100644 (file)
@@ -151,6 +151,7 @@ smtp_proto.o: ../../include/vstream.h
 smtp_proto.o: ../../include/vstring_vstream.h
 smtp_proto.o: ../../include/stringops.h
 smtp_proto.o: ../../include/mymalloc.h
+smtp_proto.o: ../../include/iostuff.h
 smtp_proto.o: ../../include/mail_params.h
 smtp_proto.o: ../../include/smtp_stream.h
 smtp_proto.o: ../../include/mail_queue.h
@@ -179,6 +180,8 @@ smtp_sasl_glue.o: ../../include/split_at.h
 smtp_sasl_glue.o: ../../include/name_mask.h
 smtp_sasl_glue.o: ../../include/mail_params.h
 smtp_sasl_glue.o: ../../include/string_list.h
+smtp_sasl_glue.o: ../../include/match_list.h
+smtp_sasl_glue.o: ../../include/match_ops.h
 smtp_sasl_glue.o: ../../include/maps.h
 smtp_sasl_glue.o: ../../include/dict.h
 smtp_sasl_glue.o: ../../include/vstream.h
index b26095fd8b5eca247602b8dbf12921fb0bf53ce0..3a8f4d1df8a907bf5903c07423de90db362e61bd 100644 (file)
@@ -82,6 +82,7 @@
 #include <vstring_vstream.h>
 #include <stringops.h>
 #include <mymalloc.h>
+#include <iostuff.h>
 
 /* Global library. */
 
@@ -178,8 +179,11 @@ int     smtp_helo(SMTP_STATE *state)
      * does not span a packet boundary. This hurts performance so it is not
      * on by default.
      */
-    if (resp->str[strspn(resp->str, "20 *\t\n")] == 0)
+    if (resp->str[strspn(resp->str, "20 *\t\n")] == 0) {
+       msg_info("enabling PIX <CRLF>.<CRLF> workaround for %s",
+                session->namaddr);
        state->features |= SMTP_FEATURE_MAYBEPIX;
+    }
 
     /*
      * See if we are talking to ourself. This should not be possible with the
@@ -196,9 +200,9 @@ int     smtp_helo(SMTP_STATE *state)
        } else if (strcasecmp(word, "ESMTP") == 0)
            state->features |= SMTP_FEATURE_ESMTP;
     }
-    if (var_smtp_always_ehlo)
+    if (var_smtp_always_ehlo && (state->features & SMTP_FEATURE_MAYBEPIX) == 0)
        state->features |= SMTP_FEATURE_ESMTP;
-    if (var_smtp_never_ehlo)
+    if (var_smtp_never_ehlo || (state->features & SMTP_FEATURE_MAYBEPIX) != 0)
        state->features &= ~SMTP_FEATURE_ESMTP;
 
     /*
@@ -657,9 +661,10 @@ int     smtp_xfer(SMTP_STATE *state)
 
            if (prev_type == REC_TYPE_CONT)     /* missing newline at end */
                smtp_fputs("", 0, session->stream);
-           if ((state->features & SMTP_FEATURE_ESMTP) == 0
-               && (state->features & SMTP_FEATURE_MAYBEPIX) != 0)
+           if ((state->features & SMTP_FEATURE_MAYBEPIX) != 0) {
                vstream_fflush(session->stream);/* hurts performance */
+               sleep(10);                      /* not to mention this */
+           }
            if (vstream_ferror(state->src))
                msg_fatal("queue file read error");
            if (rec_type != REC_TYPE_XTRA)
index e8181359bf9db1e45b30ec4a0e883191a2a13d03..f94336be3edfbbc72d1cd80c8a6a8b9200873089 100644 (file)
@@ -176,6 +176,8 @@ smtpd_check.o: ../../include/htable.h
 smtpd_check.o: ../../include/ctable.h
 smtpd_check.o: ../../include/dns.h
 smtpd_check.o: ../../include/namadr_list.h
+smtpd_check.o: ../../include/match_list.h
+smtpd_check.o: ../../include/match_ops.h
 smtpd_check.o: ../../include/domain_list.h
 smtpd_check.o: ../../include/mail_params.h
 smtpd_check.o: ../../include/canon_addr.h
@@ -187,6 +189,7 @@ smtpd_check.o: ../../include/own_inet_addr.h
 smtpd_check.o: ../../include/mail_conf.h
 smtpd_check.o: ../../include/maps.h
 smtpd_check.o: ../../include/mail_addr_find.h
+smtpd_check.o: ../../include/match_parent_style.h
 smtpd_check.o: smtpd.h
 smtpd_check.o: ../../include/mail_stream.h
 smtpd_check.o: smtpd_sasl_glue.h
@@ -208,6 +211,8 @@ smtpd_sasl_glue.o: ../../include/sys_defs.h
 smtpd_sasl_glue.o: ../../include/msg.h
 smtpd_sasl_glue.o: ../../include/mymalloc.h
 smtpd_sasl_glue.o: ../../include/namadr_list.h
+smtpd_sasl_glue.o: ../../include/match_list.h
+smtpd_sasl_glue.o: ../../include/match_ops.h
 smtpd_sasl_glue.o: ../../include/name_mask.h
 smtpd_sasl_glue.o: ../../include/mail_params.h
 smtpd_sasl_glue.o: ../../include/smtp_stream.h
index e2003ffd25d530018d5136c8449ba5618e943bb4..745c9e908a6b94bfc292188b7f6ca66abc9006b7 100644 (file)
 /* .SH "UCE control restrictions"
 /* .ad
 /* .fi
+/* .IP "\fBparent_domain_matches_subdomains\fR (versions >= 20011119)"
+/*     List of Postfix features that use \fIdomain.name\fR patterns
+/*     to match \fIsub.domain.name\fR (as opposed to
+/*     requiring \fI.domain.name\fR patterns).
 /* .IP \fBsmtpd_client_restrictions\fR
 /*     Restrict what clients may connect to this mail system.
 /* .IP \fBsmtpd_helo_required\fR
@@ -1281,7 +1285,7 @@ static void chat_reset(SMTPD_STATE *state)
      * report problems when running in stand-alone mode: postmaster notices
      * require availability of the cleanup service.
      */
-    if (state->history != 0 && state->client != VSTREAM_IN
+    if (state->history != 0 && SMTPD_STAND_ALONE(state) == 0
        && (state->error_mask & state->notify_mask))
        smtpd_chat_notify(state);
     smtpd_chat_reset(state);
index 29fb3d2d743dd8b0cee2d23d2bd86d29b1691324..20386ad73fce314299719d8a2ae41794f45bca61 100644 (file)
@@ -76,6 +76,7 @@ typedef struct SMTPD_STATE {
     VSTRING *sasl_encoded;
     VSTRING *sasl_decoded;
 #endif
+    int     warn_if_reject;
 } SMTPD_STATE;
 
 extern void smtpd_state_init(SMTPD_STATE *, VSTREAM *);
index d558c37c3b250814740ebd8ea445f7489de37abd..6bd64170662cbe0612bba2a17e1d91108ba981b8 100644 (file)
 #include <mail_conf.h>
 #include <maps.h>
 #include <mail_addr_find.h>
+#include <match_parent_style.h>
 
 /* Application-specific. */
 
@@ -339,6 +340,11 @@ static DOMAIN_LIST *relay_domains;
 static NAMADR_LIST *mynetworks;
 static NAMADR_LIST *perm_mx_networks;
 
+ /*
+  * How to do parent domain wildcard matching, if any.
+  */
+static int access_parent_style;
+
  /*
   * Pre-parsed restriction lists.
   */
@@ -452,6 +458,10 @@ static int has_required(ARGV *restrictions, char **required)
      * Recursively check list membership.
      */
     for (rest = restrictions->argv; *rest; rest++) {
+       if (strcmp(*rest, WARN_IF_REJECT) == 0 && rest[1] != 0) {
+           rest += 1;
+           continue;
+       }
        for (reqd = required; *reqd; reqd++)
            if (strcmp(*rest, *reqd) == 0)
                return (1);
@@ -481,8 +491,9 @@ static void fail_required(char *name, char **required)
      */
     example = vstring_alloc(10);
     for (reqd = required; *reqd; reqd++)
-       vstring_sprintf_append(example, "%s ", *reqd);
-    msg_fatal("parameter \"%s\": specify at least one explicit instance of: %s",
+       vstring_sprintf_append(example, "%s%s", *reqd,
+                         reqd[1] == 0 ? "" : reqd[2] == 0 ? " or " : ", ");
+    msg_fatal("parameter \"%s\": specify at least one working instance of: %s",
              name, STR(example));
 }
 
@@ -504,9 +515,15 @@ void    smtpd_check_init(void)
     /*
      * Pre-open access control lists before going to jail.
      */
-    mynetworks = namadr_list_init(var_mynetworks);
-    relay_domains = domain_list_init(var_relay_domains);
-    perm_mx_networks = namadr_list_init(var_perm_mx_networks);
+    mynetworks =
+       namadr_list_init(match_parent_style(VAR_MYNETWORKS),
+                        var_mynetworks);
+    relay_domains =
+       domain_list_init(match_parent_style(VAR_RELAY_DOMAINS),
+                        var_relay_domains);
+    perm_mx_networks =
+       namadr_list_init(match_parent_style(VAR_PERM_MX_NETWORKS),
+                        var_perm_mx_networks);
 
     /*
      * Pre-parse and pre-open the recipient maps.
@@ -524,6 +541,8 @@ void    smtpd_check_init(void)
     relocated_maps = maps_create(VAR_RELOCATED_MAPS, var_relocated_maps,
                                 DICT_FLAG_LOCK);
 
+    access_parent_style = match_parent_style(SMTPD_ACCESS_MAPS);
+
     /*
      * error_text is used for returning error responses.
      */
@@ -585,6 +604,20 @@ static int smtpd_check_reject(SMTPD_STATE *state, int error_class,
                                      char *format,...)
 {
     va_list ap;
+    int     warn_if_reject;
+    const char *whatsup;
+
+    /*
+     * Do not reject mail if we were asked to warn only. However,
+     * configuration errors cannot be converted into warnings.
+     */
+    if (state->warn_if_reject && error_class != MAIL_ERROR_SOFTWARE) {
+       warn_if_reject = 1;
+       whatsup = "reject_warning";
+    } else {
+       warn_if_reject = 0;
+       whatsup = "reject";
+    }
 
     /*
      * Update the error class mask, and format the response. XXX What about
@@ -634,22 +667,22 @@ static int smtpd_check_reject(SMTPD_STATE *state, int error_class,
      * rejected. Print the request, client name/address, and response.
      */
     if (state->recipient && state->sender) {
-       msg_info("reject: %s from %s: %s; from=<%s> to=<%s>",
-                state->where, state->namaddr, STR(error_text),
+       msg_info("%s: %s from %s: %s; from=<%s> to=<%s>",
+                whatsup, state->where, state->namaddr, STR(error_text),
                 state->sender, state->recipient);
     } else if (state->recipient) {
-       msg_info("reject: %s from %s: %s; to=<%s>",
-                state->where, state->namaddr, STR(error_text),
+       msg_info("%s: %s from %s: %s; to=<%s>",
+                whatsup, state->where, state->namaddr, STR(error_text),
                 state->recipient);
     } else if (state->sender) {
-       msg_info("reject: %s from %s: %s; from=<%s>",
-                state->where, state->namaddr, STR(error_text),
+       msg_info("%s: %s from %s: %s; from=<%s>",
+                whatsup, state->where, state->namaddr, STR(error_text),
                 state->sender);
     } else {
-       msg_info("reject: %s from %s: %s",
-                state->where, state->namaddr, STR(error_text));
+       msg_info("%s: %s from %s: %s",
+                whatsup, state->where, state->namaddr, STR(error_text));
     }
-    return (SMTPD_CHECK_REJECT);
+    return (warn_if_reject ? 0 : SMTPD_CHECK_REJECT);
 }
 
 /* reject_dict_retry - reject with temporary failure if dict lookup fails */
@@ -1542,7 +1575,7 @@ static int check_domain_access(SMTPD_STATE *state, const char *table,
 
     if ((dict = dict_handle(table)) == 0)
        msg_panic("%s: dictionary not found: %s", myname, table);
-    for (name = low_domain; /* void */ ; name = next + 1) {
+    for (name = low_domain; /* void */ ; name = next) {
        if (flags == 0 || (flags & dict->flags) != 0) {
            if ((value = dict_get(dict, name)) != 0)
                CHK_DOMAIN_RETURN(check_table_result(state, table, value,
@@ -1551,8 +1584,10 @@ static int check_domain_access(SMTPD_STATE *state, const char *table,
            if (dict_errno != 0)
                msg_fatal("%s: table lookup problem", table);
        }
-       if ((next = strchr(name, '.')) == 0)
+       if ((next = strchr(name + 1, '.')) == 0)
            break;
+       if (access_parent_style == MATCH_FLAG_PARENT)
+           next += 1;
        flags = PARTIAL;
     }
     CHK_DOMAIN_RETURN(SMTPD_CHECK_DUNNO, MISSED);
@@ -1824,6 +1859,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
     int     status = 0;
     ARGV   *list;
     int     found;
+    int     saved_recursion = state->recursion;
 
     if (msg_verbose)
        msg_info("%s: START", myname);
@@ -1833,6 +1869,15 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
        if (msg_verbose)
            msg_info("%s: name=%s", myname, name);
 
+       /*
+        * Pseudo restrictions.
+        */
+       if (strcasecmp(name, WARN_IF_REJECT) == 0) {
+           if (state->warn_if_reject == 0)
+               state->warn_if_reject = state->recursion;
+           continue;
+       }
+
        /*
         * Spoof the is_map_command() routine, so that we do not have to make
         * special cases for the implicit short-hand access map notation.
@@ -1847,14 +1892,14 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
         */
        if (strcasecmp(name, PERMIT_ALL) == 0) {
            status = SMTPD_CHECK_OK;
-           if (cpp[1] != 0)
+           if (cpp[1] != 0 && state->warn_if_reject == 0)
                msg_warn("restriction `%s' after `%s' is ignored",
                         cpp[1], PERMIT_ALL);
        } else if (strcasecmp(name, REJECT_ALL) == 0) {
            status = smtpd_check_reject(state, MAIL_ERROR_POLICY,
                                      "%d <%s>: %s rejected: Access denied",
                                  var_reject_code, reply_name, reply_class);
-           if (cpp[1] != 0)
+           if (cpp[1] != 0 && state->warn_if_reject == 0)
                msg_warn("restriction `%s' after `%s' is ignored",
                         cpp[1], REJECT_ALL);
        } else if (strcasecmp(name, REJECT_UNAUTH_PIPE) == 0) {
@@ -1963,7 +2008,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
            if (state->recipient)
                status = check_relay_domains(state, state->recipient,
                                    state->recipient, SMTPD_NAME_RECIPIENT);
-           if (cpp[1] != 0)
+           if (cpp[1] != 0 && state->warn_if_reject == 0)
                msg_warn("restriction `%s' after `%s' is ignored",
                         cpp[1], CHECK_RELAY_DOMAINS);
 #ifdef USE_SASL_AUTH
@@ -2011,12 +2056,17 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
        if (msg_verbose)
            msg_info("%s: name=%s status=%d", myname, name, status);
 
+       if (state->warn_if_reject >= state->recursion)
+           state->warn_if_reject = 0;
+
        if (status != 0)
            break;
     }
     if (msg_verbose && name == 0)
        msg_info("%s: END", myname);
 
+    state->recursion = saved_recursion;
+
     return (status);
 }
 
@@ -2035,7 +2085,7 @@ char   *smtpd_check_client(SMTPD_STATE *state)
     /*
      * Apply restrictions in the order as specified.
      */
-    state->recursion = 0;
+    state->recursion = 1;
     status = setjmp(smtpd_check_buf);
     if (status == 0 && client_restrctions->argc)
        status = generic_checks(state, client_restrctions, state->namaddr,
@@ -2081,7 +2131,7 @@ char   *smtpd_check_helo(SMTPD_STATE *state, char *helohost)
     /*
      * Apply restrictions in the order as specified.
      */
-    state->recursion = 0;
+    state->recursion = 1;
     status = setjmp(smtpd_check_buf);
     if (status == 0 && helo_restrctions->argc)
        status = generic_checks(state, helo_restrctions, state->helo_name,
@@ -2117,7 +2167,7 @@ char   *smtpd_check_mail(SMTPD_STATE *state, char *sender)
     /*
      * Apply restrictions in the order as specified.
      */
-    state->recursion = 0;
+    state->recursion = 1;
     status = setjmp(smtpd_check_buf);
     if (status == 0 && mail_restrctions->argc)
        status = generic_checks(state, mail_restrctions, sender,
@@ -2171,7 +2221,7 @@ char   *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient)
     /*
      * Apply restrictions in the order as specified.
      */
-    state->recursion = 0;
+    state->recursion = 1;
     status = setjmp(smtpd_check_buf);
     if (status == 0 && rcpt_restrctions->argc)
        status = generic_checks(state, rcpt_restrctions,
@@ -2216,7 +2266,7 @@ char   *smtpd_check_etrn(SMTPD_STATE *state, char *domain)
     /*
      * Apply restrictions in the order as specified.
      */
-    state->recursion = 0;
+    state->recursion = 1;
     status = setjmp(smtpd_check_buf);
     if (status == 0 && etrn_restrctions->argc)
        status = generic_checks(state, etrn_restrctions, domain,
@@ -2421,6 +2471,7 @@ char   *var_virt_mailbox_maps;
 char   *var_relocated_maps;
 char   *var_local_rcpt_maps;
 char   *var_perm_mx_networks;
+char   *var_par_dom_match;
 
 typedef struct {
     char   *name;
@@ -2442,7 +2493,8 @@ static STRING_TABLE string_table[] = {
     VAR_VIRT_MAILBOX_MAPS, DEF_VIRT_MAILBOX_MAPS, &var_virt_mailbox_maps,
     VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps,
     VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps,
-    VAR_PERM_MX_NETWORKS, DEF_PERM_MX_NETWORKS, &var_perm_mx_networks, 0, 0,
+    VAR_PERM_MX_NETWORKS, DEF_PERM_MX_NETWORKS, &var_perm_mx_networks,
+    VAR_PAR_DOM_MATCH, DEF_PAR_DOM_MATCH, &var_par_dom_match,
     0,
 };
 
@@ -2780,13 +2832,17 @@ int     main(int argc, char **argv)
            }
            if (strcasecmp(args->argv[0], "mynetworks") == 0) {
                namadr_list_free(mynetworks);
-               mynetworks = namadr_list_init(args->argv[1]);
+               mynetworks =
+                   namadr_list_init(match_parent_style(VAR_MYNETWORKS),
+                                    args->argv[1]);
                resp = 0;
                break;
            }
            if (strcasecmp(args->argv[0], "relay_domains") == 0) {
                domain_list_free(relay_domains);
-               relay_domains = domain_list_init(args->argv[1]);
+               relay_domains =
+                   domain_list_init(match_parent_style(VAR_RELAY_DOMAINS),
+                                    args->argv[1]);
                resp = 0;
                break;
            }
index f7c3cdd709d0e8bfda7f642f6837c708128a53d6..44f969ce9c68113f823e39c3ac3dd17815601c57 100644 (file)
@@ -6,6 +6,7 @@
 smtpd_delay_reject 0
 mynetworks 127.0.0.0/8,168.100.189.0/28
 relay_domains porcupine.org
+maps_rbl_domains blackholes.mail-abuse.org
 #
 # Test the client restrictions.
 #
index 0eaf8c02b9e217d00952db882d41ef46226cd494..2b9000267b460b48c71493df569f3be4ec6d23ed 100644 (file)
@@ -6,6 +6,7 @@
 smtpd_delay_reject 0
 mynetworks 127.0.0.0/8,168.100.189.0/28
 relay_domains porcupine.org
+maps_rbl_domains blackholes.mail-abuse.org
 #
 # Test the client restrictions.
 #
index b63c3f7054554efe9be72e275e2d6b59e10a9eed..121c9e32a5d952b87581da063c29ef67529b4391 100644 (file)
@@ -9,6 +9,8 @@ OK
 OK
 >>> relay_domains porcupine.org
 OK
+>>> maps_rbl_domains blackholes.mail-abuse.org
+OK
 >>> #
 >>> # Test the client restrictions.
 >>> #
index c8d014f6000a2013ba125cd0f53188be04513864..2bd382663759b7222eca620c0735754b90c3d551 100644 (file)
@@ -9,6 +9,8 @@ OK
 OK
 >>> relay_domains porcupine.org
 OK
+>>> maps_rbl_domains blackholes.mail-abuse.org
+OK
 >>> #
 >>> # Test the client restrictions.
 >>> #
index ca492963487f621014c416b0e4630265033e54a0..6e7236543e90a8a2fe655a0bcd9f8c736fc29705 100644 (file)
@@ -91,6 +91,7 @@ void    smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream)
     state->recursion = 0;
     state->msg_size = 0;
     state->junk_cmds = 0;
+    state->warn_if_reject = 0;
 
 #ifdef USE_SASL_AUTH
     if (SMTPD_STAND_ALONE(state))
index 7eb99744632c8b1fd3c08e7c3b0d9f3a40b771be..24a5e27849294ca69e4ef435fbf9a260892b90d0 100644 (file)
@@ -28,6 +28,9 @@
 /*     Terminate after \fIcount\fR sessions. This is for testing purposes.
 /* .IP \fB-p\fR
 /*     Disable ESMTP command pipelining.
+/* .IP \fB-P\fR
+/*     Change the server greeting so that it appears to come through
+/*     a CISCO PIX system.
 /* .IP \fB-v\fR
 /*     Show the SMTP conversations.
 /* .IP "\fB-w \fIdelay\fR"
@@ -114,6 +117,7 @@ static int max_count;
 static int disable_pipelining;
 static int fixed_delay;
 static int enable_lmtp;
+static int pretend_pix;
 
 /* ehlo_response - respond to EHLO command */
 
@@ -443,6 +447,9 @@ static void connect_event(int unused_event, char *context)
        state->read = command_read;
        state->data_state = ST_ANY;
        smtp_timeout_setup(state->stream, var_tmout);
+if (pretend_pix)
+       smtp_printf(state->stream, "220 ********");
+else
        smtp_printf(state->stream, "220 %s ESMTP", var_myhostname);
        event_enable_read(fd, read_event, (char *) state);
     }
@@ -452,7 +459,7 @@ static void connect_event(int unused_event, char *context)
 
 static void usage(char *myname)
 {
-    msg_fatal("usage: %s [-cLpv] [-n count] [-w delay] [host]:port backlog", myname);
+    msg_fatal("usage: %s [-cLpPv] [-n count] [-w delay] [host]:port backlog", myname);
 }
 
 int     main(int argc, char **argv)
@@ -469,7 +476,7 @@ int     main(int argc, char **argv)
     /*
      * Parse JCL.
      */
-    while ((ch = GETOPT(argc, argv, "cLn:pvw:")) > 0) {
+    while ((ch = GETOPT(argc, argv, "cLn:pPvw:")) > 0) {
        switch (ch) {
        case 'c':
            count++;
@@ -483,6 +490,9 @@ int     main(int argc, char **argv)
        case 'p':
            disable_pipelining = 1;
            break;
+       case 'P':
+           pretend_pix=1;
+           break;
        case 'v':
            msg_verbose++;
            break;
index baf55f69963511baaf14893529456e898f40b930..379e2395f0a43c0b6f2ced7aa0b216bbcda348ba 100644 (file)
 
 #include <mail_params.h>
 #include <maps.h>
+#include <match_parent_style.h>
 
 /* Application-specific. */
 
 #include "transport.h"
 
 static MAPS *transport_path;
+static int transport_match_parent_style;
 
 /* transport_init - pre-jail initialization */
 
@@ -77,6 +79,7 @@ void    transport_init(void)
        msg_panic("transport_init: repeated call");
     transport_path = maps_create("transport", var_transport_maps,
                                 DICT_FLAG_LOCK);
+    transport_match_parent_style = match_parent_style(VAR_TRANSPORT_MAPS);
 }
 
 /* transport_lookup - map a transport domain */
@@ -85,6 +88,7 @@ int     transport_lookup(const char *domain, VSTRING *channel, VSTRING *nexthop)
 {
     char   *low_domain = lowercase(mystrdup(domain));
     const char *name;
+    const char *next;
     const char *value;
     const char *host;
     char   *saved_value;
@@ -113,7 +117,7 @@ int     transport_lookup(const char *domain, VSTRING *channel, VSTRING *nexthop)
      * Specify if a key is partial or full, to avoid matching partial keys with
      * regular expressions.
      */
-    for (name = low_domain; name != 0; name = strchr(name + 1, '.')) {
+    for (name = low_domain; /* void */; name = next) {
        if ((value = maps_find(transport_path, name, maps_flag)) != 0) {
            saved_value = mystrdup(value);
            if ((host = split_at(saved_value, ':')) == 0 || *host == 0)
@@ -132,6 +136,10 @@ int     transport_lookup(const char *domain, VSTRING *channel, VSTRING *nexthop)
        } else if (dict_errno != 0) {
            msg_fatal("transport table lookup problem");
        }
+       if ((next = strchr(name + 1, '.')) == 0)
+           break;
+       if (transport_match_parent_style == MATCH_FLAG_PARENT)
+           next++;
        maps_flag = PARTIAL;
     }
     myfree(low_domain);
index 3ed42dbfcab94313949946639228340609b102fa..2b3c808eb0e1951b3248a03a85e352347f4a6aae 100644 (file)
 /* .sp
 /*     Syntax is \fItransport\fR:\fInexthop\fR; see \fBtransport\fR(5)
 /*     for details. The :\fInexthop\fR part is optional.
+/* .IP "\fBparent_domain_matches_subdomains\fR (versions >= 20011119)"
+/*     List of Postfix features that use \fIdomain.name\fR patterns
+/*     to match \fIsub.domain.name\fR (as opposed to
+/*     requiring \fI.domain.name\fR patterns).
 /* .IP \fBrelayhost\fR
 /*     The default host to send non-local mail to when no entry is matched
 /*     in the \fBtransport\fR(5) table.
index b31dc93aa3c2a3de26e17d4f0e3b96b1ef94acf0..eb0523dcdc1fa29ddc1814f1c671c907e9346e73 100644 (file)
@@ -23,8 +23,8 @@ SRCS  = argv.c argv_split.c basename.c binhash.c chroot_uid.c \
        clean_env.c watchdog.c spawn_command.c duplex_pipe.c sane_rename.c \
        sane_link.c unescape.c timed_read.c timed_write.c dict_tcp.c \
        hex_quote.c dict_alloc.c rand_sleep.c sane_time.c dict_debug.c \
-       sane_socketpair.c myrand.c netstring.c ctable.c attr_print.c intv.c \
-       attr_scan.c base64_code.c
+       sane_socketpair.c myrand.c netstring.c ctable.c attr_print64.c intv.c \
+       attr_scan64.c base64_code.c sock_empty_wait.c attr_print0.c attr_scan0.c
 OBJS   = argv.o argv_split.o basename.o binhash.o chroot_uid.o \
        close_on_exec.o concatenate.o dict.o dict_db.o dict_dbm.o \
        dict_env.o dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \
@@ -49,8 +49,8 @@ OBJS  = argv.o argv_split.o basename.o binhash.o chroot_uid.o \
        clean_env.o watchdog.o spawn_command.o duplex_pipe.o sane_rename.o \
        sane_link.o unescape.o timed_read.o timed_write.o dict_tcp.o \
        hex_quote.o dict_alloc.o rand_sleep.o sane_time.o dict_debug.o \
-       sane_socketpair.o myrand.o netstring.o ctable.o attr_print.o intv.o \
-       attr_scan.o base64_code.o
+       sane_socketpair.o myrand.o netstring.o ctable.o attr_print64.o intv.o \
+       attr_scan64.o base64_code.o sock_empty_wait.o attr_print0.o attr_scan0.o
 HDRS   = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
        dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_mysql.h \
        dict_ni.h dict_nis.h dict_nisplus.h dir_forest.h events.h \
@@ -84,7 +84,8 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
        mystrtok sigdelay translit valid_hostname vstream_popen \
        vstring vstring_vstream doze select_bug stream_test mac_expand \
        watchdog unescape hex_quote name_mask rand_sleep sane_time ctable \
-       inet_addr_list attr_print attr_scan base64_code
+       inet_addr_list attr_print64 attr_scan64 base64_code attr_print0 \
+       attr_scan0
 
 LIB_DIR        = ../../lib
 INC_DIR        = ../../include
@@ -288,12 +289,12 @@ inet_addr_list: $(LIB) $@.o
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-attr_print: $(LIB) $@.o
+attr_print64: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-attr_scan: $(LIB) $@.o
+attr_scan64: $(LIB) $@.o
        mv $@.o junk
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
@@ -303,6 +304,16 @@ base64_code: $(LIB) $@.o
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
+attr_print0: $(LIB) $@.o
+       mv $@.o junk
+       $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
+       mv junk $@.o
+
+attr_scan0: $(LIB) $@.o
+       mv $@.o junk
+       $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
+       mv junk $@.o
+
 depend: $(MAKES)
        (sed '1,/^# do not edit/!d' Makefile.in; \
        set -e; for i in [a-z][a-z0-9]*.c; do \
@@ -316,7 +327,7 @@ stream_test: stream_test.c $(LIB)
 
 tests: valid_hostname_test mac_expand_test dict_test unescape_test \
        hex_quote_test ctable_test inet_addr_list_test base64_code_test \
-       attr_scan_test
+       attr_scan64_test attr_scan0_test
 
 valid_hostname_test: valid_hostname valid_hostname.in valid_hostname.ref
        ./valid_hostname <valid_hostname.in 2>valid_hostname.tmp
@@ -352,10 +363,15 @@ inet_addr_list_test: inet_addr_list
 base64_code_test: base64_code
        ./base64_code
 
-attr_scan_test: attr_print attr_scan attr_scan.ref
-       (./attr_print 2>&3 | (sleep 1; ./attr_scan)) >attr_scan.tmp 2>&1 3>&1
-       diff attr_scan.ref attr_scan.tmp
-       rm -f attr_scan.tmp
+attr_scan64_test: attr_print64 attr_scan64 attr_scan64.ref
+       (./attr_print64 2>&3 | (sleep 1; ./attr_scan64)) >attr_scan64.tmp 2>&1 3>&1
+       diff attr_scan64.ref attr_scan64.tmp
+       rm -f attr_scan64.tmp
+
+attr_scan0_test: attr_print0 attr_scan0 attr_scan0.ref
+       (./attr_print0 2>&3 | (sleep 1; ./attr_scan0)) >attr_scan0.tmp 2>&1 3>&1
+       diff attr_scan0.ref attr_scan0.tmp
+       rm -f attr_scan0.tmp
 
 DB_TYPE        = `../postconf/postconf -h default_database_type`
 
@@ -391,6 +407,24 @@ attr_print.o: htable.h
 attr_print.o: base64_code.h
 attr_print.o: vstring.h
 attr_print.o: attr.h
+attr_print0.o: attr_print0.c
+attr_print0.o: sys_defs.h
+attr_print0.o: msg.h
+attr_print0.o: mymalloc.h
+attr_print0.o: vstream.h
+attr_print0.o: vbuf.h
+attr_print0.o: htable.h
+attr_print0.o: attr.h
+attr_print64.o: attr_print64.c
+attr_print64.o: sys_defs.h
+attr_print64.o: msg.h
+attr_print64.o: mymalloc.h
+attr_print64.o: vstream.h
+attr_print64.o: vbuf.h
+attr_print64.o: htable.h
+attr_print64.o: base64_code.h
+attr_print64.o: vstring.h
+attr_print64.o: attr.h
 attr_scan.o: attr_scan.c
 attr_scan.o: sys_defs.h
 attr_scan.o: msg.h
@@ -401,6 +435,26 @@ attr_scan.o: vstring.h
 attr_scan.o: htable.h
 attr_scan.o: base64_code.h
 attr_scan.o: attr.h
+attr_scan0.o: attr_scan0.c
+attr_scan0.o: sys_defs.h
+attr_scan0.o: msg.h
+attr_scan0.o: mymalloc.h
+attr_scan0.o: vstream.h
+attr_scan0.o: vbuf.h
+attr_scan0.o: vstring.h
+attr_scan0.o: vstring_vstream.h
+attr_scan0.o: htable.h
+attr_scan0.o: attr.h
+attr_scan64.o: attr_scan64.c
+attr_scan64.o: sys_defs.h
+attr_scan64.o: msg.h
+attr_scan64.o: mymalloc.h
+attr_scan64.o: vstream.h
+attr_scan64.o: vbuf.h
+attr_scan64.o: vstring.h
+attr_scan64.o: htable.h
+attr_scan64.o: base64_code.h
+attr_scan64.o: attr.h
 base64_code.o: base64_code.c
 base64_code.o: sys_defs.h
 base64_code.o: msg.h
@@ -782,6 +836,7 @@ match_list.o: vstring_vstream.h
 match_list.o: stringops.h
 match_list.o: argv.h
 match_list.o: dict.h
+match_list.o: match_ops.h
 match_list.o: match_list.h
 match_ops.o: match_ops.c
 match_ops.o: sys_defs.h
@@ -979,6 +1034,10 @@ skipblanks.o: sys_defs.h
 skipblanks.o: stringops.h
 skipblanks.o: vstring.h
 skipblanks.o: vbuf.h
+sock_empty_wait.o: sock_empty_wait.c
+sock_empty_wait.o: sys_defs.h
+sock_empty_wait.o: msg.h
+sock_empty_wait.o: iostuff.h
 spawn_command.o: spawn_command.c
 spawn_command.o: sys_defs.h
 spawn_command.o: msg.h
index 1033b53b318e32fe34d0e517657aa6c8158b9fa2..c656dadf8e1ece6281a12875806b12980a6c2003 100644 (file)
@@ -28,6 +28,7 @@
 #define ATTR_TYPE_NUM          1       /* Unsigned integer */
 #define ATTR_TYPE_STR          2       /* Character string */
 #define ATTR_TYPE_HASH         3       /* Hash table */
+#define ATTR_TYPE_LONG         4       /* Unsigned long */
 
  /*
   * Flags that control processing. See attr_scan(3) for documentation.
 #define ATTR_FLAG_STRICT       (ATTR_FLAG_MISSING | ATTR_FLAG_EXTRA)
 #define ATTR_FLAG_ALL          (07)
 
+#define attr_print     attr_print0
+#define attr_vprint    attr_vprint0
+#define attr_scan      attr_scan0
+#define attr_vscan     attr_vscan0
+
+ /*
+  * attr_print64.c.
+  */
+extern int attr_print64(VSTREAM *, int,...);
+extern int attr_vprint64(VSTREAM *, int, va_list);
+
+ /*
+  * attr_scan64.c.
+  */
+extern int attr_scan64(VSTREAM *, int,...);
+extern int attr_vscan64(VSTREAM *, int, va_list);
+
  /*
-  * attr_print.c.
+  * attr_print0.c.
   */
-extern int attr_print(VSTREAM *, int,...);
-extern int attr_vprint(VSTREAM *, int, va_list);
+extern int attr_print0(VSTREAM *, int,...);
+extern int attr_vprint0(VSTREAM *, int, va_list);
 
  /*
-  * attr_scan.c.
+  * attr_scan0.c.
   */
-extern int attr_scan(VSTREAM *, int,...);
-extern int attr_vscan(VSTREAM *, int, va_list);
+extern int attr_scan0(VSTREAM *, int,...);
+extern int attr_vscan0(VSTREAM *, int, va_list);
 
  /*
   * Attribute names for testing the compatibility of the read and write
@@ -59,6 +77,7 @@ extern int attr_vscan(VSTREAM *, int, va_list);
 #ifdef TEST
 #define ATTR_NAME_NUM          "number"
 #define ATTR_NAME_STR          "string"
+#define ATTR_NAME_LONG         "long_number"
 #endif
 
 /* LICENSE
diff --git a/postfix/src/util/attr_print0.c b/postfix/src/util/attr_print0.c
new file mode 100644 (file)
index 0000000..3678e24
--- /dev/null
@@ -0,0 +1,208 @@
+/*++
+/* NAME
+/*     attr_print0 3
+/* SUMMARY
+/*     send attributes over byte stream
+/* SYNOPSIS
+/*     #include <attr.h>
+/*
+/*     int     attr_print0(fp, flags, type, name, ...)
+/*     VSTREAM fp;
+/*     int     flags;
+/*     int     type;
+/*     char    *name;
+/*
+/*     int     attr_vprint0(fp, flags, ap)
+/*     VSTREAM fp;
+/*     int     flags;
+/*     va_list ap;
+/* DESCRIPTION
+/*     attr_print0() takes zero or more (name, value) simple attributes
+/*     or (name, count, value) list attributes, and converts its input
+/*     to a byte stream that can be recovered with attr_scan0(). The stream
+/*     is not flushed.
+/*
+/*     attr_vprint0() provides an alternate interface that is convenient
+/*     for calling from within variadoc functions.
+/*
+/*     Attributes are sent in the requested order as specified with the
+/*     attr_print0() argument list. This routine satisfies the formatting
+/*     rules as outlined in attr_scan0(3).
+/*
+/*     Arguments:
+/* .IP fp
+/*     Stream to write the result to.
+/* .IP flags
+/*     The bit-wise OR of zero or more of the following.
+/* .RS
+/* .IP ATTR_FLAG_MORE
+/*     After sending the requested attributes, leave the output stream in
+/*     a state that is usable for more attribute sending operations on
+/*     the same output attribute list.
+/*     By default, attr_print0() automatically appends an attribute list
+/*     terminator when it has sent the last requested attribute.
+/* .RE
+/* .IP type
+/*     The type determines the arguments that follow.
+/* .RS
+/* .IP "ATTR_TYPE_NUM (char *, int)"
+/*     This argument is followed by an attribute name and an integer.
+/* .IP "ATTR_TYPE_NUM (char *, long)"
+/*     This argument is followed by an attribute name and a long integer.
+/* .IP "ATTR_TYPE_STR (char *, char *)"
+/*     This argument is followed by an attribute name and a null-terminated
+/*     string.
+/* .IP "ATTR_TYPE_HASH (HTABLE *)"
+/*     The content of the hash table is sent as a sequence of string-valued
+/*     attributes with names equal to the hash table lookup key.
+/* .IP ATTR_TYPE_END
+/*     This terminates the attribute list.
+/* .RE
+/* DIAGNOSTICS
+/*     The result value is 0 in case of success, VSTREAM_EOF in case
+/*     of trouble.
+/*
+/*     Panic: interface violation. All system call errors are fatal.
+/* SEE ALSO
+/*     attr_scan0(3) recover attributes from byte stream
+/* 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 <stdarg.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <vstream.h>
+#include <htable.h>
+#include <attr.h>
+
+/* attr_vprint0 - send attribute list to stream */
+
+int     attr_vprint0(VSTREAM *fp, int flags, va_list ap)
+{
+    const char *myname = "attr_print0";
+    int     attr_type;
+    char   *attr_name;
+    unsigned int_val;
+    unsigned long long_val;
+    char   *str_val;
+    HTABLE_INFO **ht_info_list;
+    HTABLE_INFO **ht;
+
+    /*
+     * Sanity check.
+     */
+    if (flags & ~ATTR_FLAG_ALL)
+       msg_panic("%s: bad flags: 0x%x", myname, flags);
+
+    /*
+     * Iterate over all (type, name, value) triples, and produce output on
+     * the fly.
+     */
+    while ((attr_type = va_arg(ap, int)) != ATTR_TYPE_END) {
+       switch (attr_type) {
+       case ATTR_TYPE_NUM:
+           attr_name = va_arg(ap, char *);
+           vstream_fwrite(fp, attr_name, strlen(attr_name) + 1);
+           int_val = va_arg(ap, int);
+           vstream_fprintf(fp, "%u", (unsigned) int_val);
+           VSTREAM_PUTC('\0', fp);
+           if (msg_verbose)
+               msg_info("send attr %s = %u", attr_name, int_val);
+           break;
+       case ATTR_TYPE_LONG:
+           attr_name = va_arg(ap, char *);
+           vstream_fwrite(fp, attr_name, strlen(attr_name) + 1);
+           long_val = va_arg(ap, unsigned long);
+           vstream_fprintf(fp, "%lu", (unsigned long) long_val);
+           VSTREAM_PUTC('\0', fp);
+           if (msg_verbose)
+               msg_info("send attr %s = %lu", attr_name, long_val);
+           break;
+       case ATTR_TYPE_STR:
+           attr_name = va_arg(ap, char *);
+           vstream_fwrite(fp, attr_name, strlen(attr_name) + 1);
+           str_val = va_arg(ap, char *);
+           vstream_fwrite(fp, str_val, strlen(str_val) + 1);
+           if (msg_verbose)
+               msg_info("send attr %s = %s", attr_name, str_val);
+           break;
+       case ATTR_TYPE_HASH:
+           ht_info_list = htable_list(va_arg(ap, HTABLE *));
+           for (ht = ht_info_list; *ht; ht++) {
+               vstream_fwrite(fp, ht[0]->key, strlen(ht[0]->key) + 1);
+               vstream_fwrite(fp, ht[0]->value, strlen(ht[0]->value) + 1);
+               if (msg_verbose)
+                   msg_info("send attr name %s value %s",
+                            ht[0]->key, ht[0]->value);
+           }
+           myfree((char *) ht_info_list);
+           break;
+       default:
+           msg_panic("%s: unknown type code: %d", myname, attr_type);
+       }
+    }
+    if ((flags & ATTR_FLAG_MORE) == 0)
+       VSTREAM_PUTC('\0', fp);
+    return (vstream_ferror(fp));
+}
+
+int     attr_print0(VSTREAM *fp, int flags,...)
+{
+    va_list ap;
+    int     ret;
+
+    va_start(ap, flags);
+    ret = attr_vprint0(fp, flags, ap);
+    va_end(ap);
+    return (ret);
+}
+
+#ifdef TEST
+
+ /*
+  * Proof of concept test program.  Mirror image of the attr_scan0 test
+  * program.
+  */
+#include <msg_vstream.h>
+
+int     main(int unused_argc, char **argv)
+{
+    HTABLE *table = htable_create(1);
+
+    msg_vstream_init(argv[0], VSTREAM_ERR);
+    msg_verbose = 1;
+    htable_enter(table, "foo-name", mystrdup("foo-value"));
+    htable_enter(table, "bar-name", mystrdup("bar-value"));
+    attr_print0(VSTREAM_OUT, ATTR_FLAG_NONE,
+               ATTR_TYPE_NUM, ATTR_NAME_NUM, 4711,
+               ATTR_TYPE_LONG, ATTR_NAME_LONG, 1234,
+               ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
+               ATTR_TYPE_HASH, table,
+               ATTR_TYPE_END);
+    attr_print0(VSTREAM_OUT, ATTR_FLAG_NONE,
+               ATTR_TYPE_NUM, ATTR_NAME_NUM, 4711,
+               ATTR_TYPE_LONG, ATTR_NAME_LONG, 1234,
+               ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
+               ATTR_TYPE_END);
+    if (vstream_fflush(VSTREAM_OUT) != 0)
+       msg_fatal("write error: %m");
+
+    htable_free(table, myfree);
+    return (0);
+}
+
+#endif
similarity index 63%
rename from postfix/src/util/attr_print.c
rename to postfix/src/util/attr_print64.c
index fe38ea6fd96fbfe8f10dd425ff84515e0a972ca6..2c64c06d7c85ee01643feb38060b271069182b70 100644 (file)
@@ -1,33 +1,33 @@
 /*++
 /* NAME
-/*     attr_print 3
+/*     attr_print64 3
 /* SUMMARY
 /*     send attributes over byte stream
 /* SYNOPSIS
 /*     #include <attr.h>
 /*
-/*     int     attr_print(fp, flags, type, name, ...)
+/*     int     attr_print64(fp, flags, type, name, ...)
 /*     VSTREAM fp;
 /*     int     flags;
 /*     int     type;
 /*     char    *name;
 /*
-/*     int     attr_vprint(fp, flags, ap)
+/*     int     attr_vprint64(fp, flags, ap)
 /*     VSTREAM fp;
 /*     int     flags;
 /*     va_list ap;
 /* DESCRIPTION
-/*     attr_print() takes zero or more (name, value) simple attributes
+/*     attr_print64() takes zero or more (name, value) simple attributes
 /*     or (name, count, value) list attributes, and converts its input
-/*     to a byte stream that can be recovered with attr_scan(). The stream
+/*     to a byte stream that can be recovered with attr_scan64(). The stream
 /*     is not flushed.
 /*
-/*     attr_vprint() provides an alternate interface that is convenient
+/*     attr_vprint64() provides an alternate interface that is convenient
 /*     for calling from within variadoc functions.
 /*
 /*     Attributes are sent in the requested order as specified with the
-/*     attr_print() argument list. This routine satisfies the formatting
-/*     rules as outlined in attr_scan(3).
+/*     attr_print64() argument list. This routine satisfies the formatting
+/*     rules as outlined in attr_scan64(3).
 /*
 /*     Arguments:
 /* .IP fp
@@ -39,7 +39,7 @@
 /*     After sending the requested attributes, leave the output stream in
 /*     a state that is usable for more attribute sending operations on
 /*     the same output attribute list.
-/*     By default, attr_print() automatically appends an attribute list
+/*     By default, attr_print64() automatically appends an attribute list
 /*     terminator when it has sent the last requested attribute.
 /* .RE
 /* .IP type
@@ -47,6 +47,8 @@
 /* .RS
 /* .IP "ATTR_TYPE_NUM (char *, int)"
 /*     This argument is followed by an attribute name and an integer.
+/* .IP "ATTR_TYPE_NUM (char *, long)"
+/*     This argument is followed by an attribute name and a long integer.
 /* .IP "ATTR_TYPE_STR (char *, char *)"
 /*     This argument is followed by an attribute name and a null-terminated
 /*     string.
@@ -62,7 +64,7 @@
 /*
 /*     Panic: interface violation. All system call errors are fatal.
 /* SEE ALSO
-/*     attr_scan(3) recover attributes from byte stream
+/*     attr_scan64(3) recover attributes from byte stream
 /* LICENSE
 /* .ad
 /* .fi
@@ -91,9 +93,9 @@
 #define STR(x) vstring_str(x)
 #define LEN(x) VSTRING_LEN(x)
 
-/* attr_print_str - encode and send attribute information */
+/* attr_print64_str - encode and send attribute information */
 
-static void attr_print_str(VSTREAM *fp, const char *str, int len)
+static void attr_print64_str(VSTREAM *fp, const char *str, int len)
 {
     static VSTRING *base64_buf;
 
@@ -104,7 +106,7 @@ static void attr_print_str(VSTREAM *fp, const char *str, int len)
     vstream_fputs(STR(base64_buf), fp);
 }
 
-static void attr_print_num(VSTREAM *fp, unsigned num)
+static void attr_print64_num(VSTREAM *fp, unsigned num)
 {
     static VSTRING *plain;
 
@@ -112,17 +114,29 @@ static void attr_print_num(VSTREAM *fp, unsigned num)
        plain = vstring_alloc(10);
 
     vstring_sprintf(plain, "%u", num);
-    attr_print_str(fp, STR(plain), LEN(plain));
+    attr_print64_str(fp, STR(plain), LEN(plain));
 }
 
-/* attr_vprint - send attribute list to stream */
+static void attr_print64_long_num(VSTREAM *fp, unsigned long long_num)
+{
+    static VSTRING *plain;
+
+    if (plain == 0)
+       plain = vstring_alloc(10);
+
+    vstring_sprintf(plain, "%lu", long_num);
+    attr_print64_str(fp, STR(plain), LEN(plain));
+}
+
+/* attr_vprint64 - send attribute list to stream */
 
-int     attr_vprint(VSTREAM *fp, int flags, va_list ap)
+int     attr_vprint64(VSTREAM *fp, int flags, va_list ap)
 {
-    const char *myname = "attr_print";
+    const char *myname = "attr_print64";
     int     attr_type;
     char   *attr_name;
     unsigned int_val;
+    unsigned long long_val;
     char   *str_val;
     HTABLE_INFO **ht_info_list;
     HTABLE_INFO **ht;
@@ -141,28 +155,37 @@ int     attr_vprint(VSTREAM *fp, int flags, va_list ap)
        switch (attr_type) {
        case ATTR_TYPE_NUM:
            attr_name = va_arg(ap, char *);
-           attr_print_str(fp, attr_name, strlen(attr_name));
+           attr_print64_str(fp, attr_name, strlen(attr_name));
            int_val = va_arg(ap, int);
            VSTREAM_PUTC(':', fp);
-           attr_print_num(fp, (unsigned) int_val);
+           attr_print64_num(fp, (unsigned) int_val);
            if (msg_verbose)
                msg_info("send attr %s = %u", attr_name, int_val);
            break;
+       case ATTR_TYPE_LONG:
+           attr_name = va_arg(ap, char *);
+           attr_print64_str(fp, attr_name, strlen(attr_name));
+           long_val = va_arg(ap, long);
+           VSTREAM_PUTC(':', fp);
+           attr_print64_long_num(fp, (unsigned long) long_val);
+           if (msg_verbose)
+               msg_info("send attr %s = %lu", attr_name, long_val);
+           break;
        case ATTR_TYPE_STR:
            attr_name = va_arg(ap, char *);
-           attr_print_str(fp, attr_name, strlen(attr_name));
+           attr_print64_str(fp, attr_name, strlen(attr_name));
            str_val = va_arg(ap, char *);
            VSTREAM_PUTC(':', fp);
-           attr_print_str(fp, str_val, strlen(str_val));
+           attr_print64_str(fp, str_val, strlen(str_val));
            if (msg_verbose)
                msg_info("send attr %s = %s", attr_name, str_val);
            break;
        case ATTR_TYPE_HASH:
            ht_info_list = htable_list(va_arg(ap, HTABLE *));
            for (ht = ht_info_list; *ht; ht++) {
-               attr_print_str(fp, ht[0]->key, strlen(ht[0]->key));
+               attr_print64_str(fp, ht[0]->key, strlen(ht[0]->key));
                VSTREAM_PUTC(':', fp);
-               attr_print_str(fp, ht[0]->value, strlen(ht[0]->value));
+               attr_print64_str(fp, ht[0]->value, strlen(ht[0]->value));
                if (msg_verbose)
                    msg_info("send attr name %s value %s",
                             ht[0]->key, ht[0]->value);
@@ -181,13 +204,13 @@ int     attr_vprint(VSTREAM *fp, int flags, va_list ap)
     return (vstream_ferror(fp));
 }
 
-int     attr_print(VSTREAM *fp, int flags,...)
+int     attr_print64(VSTREAM *fp, int flags,...)
 {
     va_list ap;
     int     ret;
 
     va_start(ap, flags);
-    ret = attr_vprint(fp, flags, ap);
+    ret = attr_vprint64(fp, flags, ap);
     va_end(ap);
     return (ret);
 }
@@ -195,7 +218,7 @@ int     attr_print(VSTREAM *fp, int flags,...)
 #ifdef TEST
 
  /*
-  * Proof of concept test program.  Mirror image of the attr_scan test
+  * Proof of concept test program.  Mirror image of the attr_scan64 test
   * program.
   */
 #include <msg_vstream.h>
@@ -208,15 +231,17 @@ int     main(int unused_argc, char **argv)
     msg_verbose = 1;
     htable_enter(table, "foo-name", mystrdup("foo-value"));
     htable_enter(table, "bar-name", mystrdup("bar-value"));
-    attr_print(VSTREAM_OUT, ATTR_FLAG_NONE,
-              ATTR_TYPE_NUM, ATTR_NAME_NUM, 4711,
-              ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
-              ATTR_TYPE_HASH, table,
-              ATTR_TYPE_END);
-    attr_print(VSTREAM_OUT, ATTR_FLAG_NONE,
-              ATTR_TYPE_NUM, ATTR_NAME_NUM, 4711,
-              ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
-              ATTR_TYPE_END);
+    attr_print64(VSTREAM_OUT, ATTR_FLAG_NONE,
+                ATTR_TYPE_NUM, ATTR_NAME_NUM, 4711,
+                ATTR_TYPE_LONG, ATTR_NAME_LONG, 1234,
+                ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
+                ATTR_TYPE_HASH, table,
+                ATTR_TYPE_END);
+    attr_print64(VSTREAM_OUT, ATTR_FLAG_NONE,
+                ATTR_TYPE_NUM, ATTR_NAME_NUM, 4711,
+                ATTR_TYPE_LONG, ATTR_NAME_LONG, 1234,
+                ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
+                ATTR_TYPE_END);
     if (vstream_fflush(VSTREAM_OUT) != 0)
        msg_fatal("write error: %m");
 
diff --git a/postfix/src/util/attr_scan0.c b/postfix/src/util/attr_scan0.c
new file mode 100644 (file)
index 0000000..9ec3759
--- /dev/null
@@ -0,0 +1,440 @@
+/*++
+/* NAME
+/*     attr_scan0 3
+/* SUMMARY
+/*     recover attributes from byte stream
+/* SYNOPSIS
+/*     #include <attr.h>
+/*
+/*     int     attr_scan0(fp, flags, type, name, ...)
+/*     VSTREAM fp;
+/*     int     flags;
+/*     int     type;
+/*     char    *name;
+/*
+/*     int     attr_vscan0(fp, flags, ap)
+/*     VSTREAM fp;
+/*     int     flags;
+/*     va_list ap;
+/* DESCRIPTION
+/*     attr_scan0() takes zero or more (name, value) request attributes
+/*     and recovers the attribute values from the byte stream that was
+/*     possibly generated by attr_print0().
+/*
+/*     attr_vscan0() provides an alternative interface that is convenient
+/*     for calling from within a variadic function.
+/*
+/*     The input stream is formatted as follows, where (item)* stands
+/*     for zero or more instances of the specified item, and where
+/*     (item1 | item2) stands for choice:
+/*
+/* .in +5
+/*     attr-list :== simple-attr* null
+/* .br
+/*     simple-attr :== attr-name null attr-value null
+/* .br
+/*     attr-name :== any string not containing null
+/* .br
+/*     attr-value :== any string not containing null
+/* .br
+/*     null :== the ASCII null character
+/* .in
+/*
+/*     All attribute names and attribute values are sent as null terminated
+/*     strings. Each string must be no longer than 2*var_line_limit
+/*     characters. The formatting rules favor implementations in C.
+/*
+/*      Normally, attributes must be received in the sequence as specified with
+/*     the attr_scan0() argument list.  The input stream may contain additional
+/*     attributes at any point in the input stream, including additional
+/*     instances of requested attributes.
+/*
+/*     Additional input attributes or input attribute instances are silently
+/*     skipped over, unless the ATTR_FLAG_EXTRA processing flag is specified
+/*     (see below). This allows for some flexibility in the evolution of
+/*     protocols while still providing the option of being strict where
+/*     this is desirable.
+/*
+/*     Arguments:
+/* .IP fp
+/*     Stream to recover the input attributes from.
+/* .IP flags
+/*     The bit-wise OR of zero or more of the following.
+/* .RS
+/* .IP ATTR_FLAG_MISSING
+/*     Log a warning when the input attribute list terminates before all
+/*     requested attributes are recovered. It is always an error when the
+/*     input stream ends without the newline attribute list terminator.
+/* .IP ATTR_FLAG_EXTRA
+/*     Log a warning and stop attribute recovery when the input stream
+/*     contains an attribute that was not requested. This includes the
+/*     case of additional instances of a requested attribute.
+/* .IP ATTR_FLAG_MORE
+/*     After recovering the requested attributes, leave the input stream
+/*     in a state that is usable for more attr_scan0() operations from the
+/*     same input attribute list.
+/*     By default, attr_scan0() skips forward past the input attribute list
+/*     terminator.
+/* .IP ATTR_FLAG_STRICT
+/*     For convenience, this value combines both ATTR_FLAG_MISSING and
+/*     ATTR_FLAG_EXTRA.
+/* .IP ATTR_FLAG_NONE
+/*     For convenience, this value requests none of the above.
+/* .RE
+/* .IP type
+/*     The type argument determines the arguments that follow.
+/* .RS
+/* .IP "ATTR_TYPE_NUM (char *, int *)"
+/*     This argument is followed by an attribute name and an integer pointer.
+/* .IP "ATTR_TYPE_LONG (char *, long *)"
+/*     This argument is followed by an attribute name and a long pointer.
+/* .IP "ATTR_TYPE_STR (char *, VSTRING *)"
+/*     This argument is followed by an attribute name and a VSTRING pointer.
+/* .IP "ATTR_TYPE_HASH (HTABLE *)"
+/*     All further input attributes are processed as string attributes.
+/*     No specific attribute sequence is enforced.
+/*     All attributes up to the attribute list terminator are read,
+/*     but only the first instance of each attribute is stored.
+/* .sp
+/*     The attribute string values are stored in the hash table under
+/*     keys equal to the attribute name (obtained from the input stream).
+/*     Values from the input stream are added to the hash table. Existing
+/*     hash table entries are not replaced.
+/* .sp
+/*     N.B. This construct must be followed by an ATTR_TYPE_END argument.
+/* .IP ATTR_TYPE_END
+/*     This argument terminates the requested attribute list.
+/* .RE
+/* BUGS
+/*     ATTR_TYPE_HASH accepts attributes with arbitrary names from possibly
+/*     untrusted sources. This is unsafe, unless the resulting table is
+/*     queried only with known to be good attribute names.
+/* DIAGNOSTICS
+/*     attr_scan0() and attr_vscan0() return -1 when malformed input is
+/*     detected (string too long, incomplete line, missing end marker).
+/*     Otherwise, the result value is the number of attributes that were
+/*     successfully recovered from the input stream (a hash table counts
+/*     as the number of entries stored into the table).
+/*
+/*     Panic: interface violation. All system call errors are fatal.
+/* SEE ALSO
+/*     attr_print0(3) send attributes over byte stream.
+/* 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 <stdarg.h>
+#include <stdio.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <vstream.h>
+#include <vstring.h>
+#include <vstring_vstream.h>
+#include <htable.h>
+#include <attr.h>
+
+/* Application specific. */
+
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
+/* attr_scan0_string - pull a string from the input stream */
+
+static int attr_scan0_string(VSTREAM *fp, VSTRING *plain_buf, const char *context)
+{
+    extern int var_line_limit;         /* XXX */
+    int     limit = var_line_limit * 2;
+    int     ch;
+
+    if ((ch = vstring_get_null(plain_buf, fp)) == VSTREAM_EOF) {
+       msg_warn("premature end-of-input from %s while reading %s",
+                VSTREAM_PATH(fp), context);
+       return (-1);
+    }
+    if (ch != 0) {
+       msg_warn("string length > %d characters from %s while reading %s",
+                limit, VSTREAM_PATH(fp), context);
+       return (-1);
+    }
+    if (msg_verbose)
+       msg_info("%s: %s", context, *STR(plain_buf) ? STR(plain_buf) : "(end)");
+    return (ch);
+}
+
+/* attr_scan0_number - pull a number from the input stream */
+
+static int attr_scan0_number(VSTREAM *fp, unsigned *ptr, VSTRING *str_buf,
+                                    const char *context)
+{
+    char    junk = 0;
+    int     ch;
+
+    if ((ch = attr_scan0_string(fp, str_buf, context)) < 0)
+       return (-1);
+    if (sscanf(STR(str_buf), "%u%c", ptr, &junk) != 1 || junk != 0) {
+       msg_warn("malformed numerical data from %s while reading %s: %.100s",
+                VSTREAM_PATH(fp), context, STR(str_buf));
+       return (-1);
+    }
+    return (ch);
+}
+
+/* attr_scan0_long_number - pull a number from the input stream */
+
+static int attr_scan0_long_number(VSTREAM *fp, unsigned long *ptr,
+                                         VSTRING *str_buf,
+                                         const char *context)
+{
+    char    junk = 0;
+    int     ch;
+
+    if ((ch = attr_scan0_string(fp, str_buf, context)) < 0)
+       return (-1);
+    if (sscanf(STR(str_buf), "%lu%c", ptr, &junk) != 1 || junk != 0) {
+       msg_warn("malformed numerical data from %s while reading %s: %.100s",
+                VSTREAM_PATH(fp), context, STR(str_buf));
+       return (-1);
+    }
+    return (ch);
+}
+
+/* attr_vscan0 - receive attribute list from stream */
+
+int     attr_vscan0(VSTREAM *fp, int flags, va_list ap)
+{
+    const char *myname = "attr_scan0";
+    static VSTRING *str_buf = 0;
+    static VSTRING *name_buf = 0;
+    int     wanted_type = -1;
+    char   *wanted_name;
+    unsigned int *number;
+    unsigned long *long_number;
+    VSTRING *string;
+    HTABLE *hash_table;
+    int     ch;
+    int     conversions;
+
+    /*
+     * Sanity check.
+     */
+    if (flags & ~ATTR_FLAG_ALL)
+       msg_panic("%s: bad flags: 0x%x", myname, flags);
+
+    /*
+     * Initialize.
+     */
+    if (str_buf == 0) {
+       str_buf = vstring_alloc(10);
+       name_buf = vstring_alloc(10);
+    }
+
+    /*
+     * Iterate over all (type, name, value) triples.
+     */
+    for (conversions = 0; /* void */ ; conversions++) {
+
+       /*
+        * Determine the next attribute type and attribute name on the
+        * caller's wish list.
+        * 
+        * If we're reading into a hash table, we already know that the
+        * attribute value is string-valued, and we get the attribute name
+        * from the input stream instead. This is secure only when the
+        * resulting table is queried with known to be good attribute names.
+        */
+       if (wanted_type != ATTR_TYPE_HASH) {
+           wanted_type = va_arg(ap, int);
+           if (wanted_type == ATTR_TYPE_END) {
+               if ((flags & ATTR_FLAG_MORE) != 0)
+                   return (conversions);
+               wanted_name = "(list terminator)";
+           } else if (wanted_type == ATTR_TYPE_HASH) {
+               wanted_name = "(any attribute name or list terminator)";
+               hash_table = va_arg(ap, HTABLE *);
+               if (va_arg(ap, int) !=ATTR_TYPE_END)
+                   msg_panic("%s: ATTR_TYPE_HASH not followed by ATTR_TYPE_END",
+                             myname);
+           } else {
+               wanted_name = va_arg(ap, char *);
+           }
+       }
+
+       /*
+        * Locate the next attribute of interest in the input stream.
+        */
+       for (;;) {
+
+           /*
+            * Get the name of the next attribute. Hitting EOF is always bad.
+            * Hitting the end-of-input early is OK if the caller is prepared
+            * to deal with missing inputs.
+            */
+           if (msg_verbose)
+               msg_info("%s: wanted attribute: %s",
+                        VSTREAM_PATH(fp), wanted_name);
+           if ((ch = attr_scan0_string(fp, name_buf,
+                                   "input attribute name")) == VSTREAM_EOF)
+               return (-1);
+           if (LEN(name_buf) == 0) {
+               if (wanted_type == ATTR_TYPE_END
+                   || wanted_type == ATTR_TYPE_HASH)
+                   return (conversions);
+               if ((flags & ATTR_FLAG_MISSING) != 0)
+                   msg_warn("missing attribute %s in input from %s",
+                            wanted_name, VSTREAM_PATH(fp));
+               return (conversions);
+           }
+
+           /*
+            * See if the caller asks for this attribute.
+            */
+           if (wanted_type == ATTR_TYPE_HASH
+               || (wanted_type != ATTR_TYPE_END
+                   && strcmp(wanted_name, STR(name_buf)) == 0))
+               break;
+           if ((flags & ATTR_FLAG_EXTRA) != 0) {
+               msg_warn("spurious attribute %s in input from %s",
+                        STR(name_buf), VSTREAM_PATH(fp));
+               return (conversions);
+           }
+
+           /*
+            * Skip over this attribute. The caller does not ask for it.
+            */
+           (void) attr_scan0_string(fp, str_buf, "input attribute value");
+       }
+
+       /*
+        * Do the requested conversion.
+        */
+       switch (wanted_type) {
+       case ATTR_TYPE_NUM:
+           number = va_arg(ap, unsigned int *);
+           if ((ch = attr_scan0_number(fp, number, str_buf,
+                                       "input attribute value")) < 0)
+               return (-1);
+           break;
+       case ATTR_TYPE_LONG:
+           long_number = va_arg(ap, unsigned long *);
+           if ((ch = attr_scan0_long_number(fp, long_number, str_buf,
+                                            "input attribute value")) < 0)
+               return (-1);
+           break;
+       case ATTR_TYPE_STR:
+           string = va_arg(ap, VSTRING *);
+           if ((ch = attr_scan0_string(fp, string,
+                                       "input attribute value")) < 0)
+               return (-1);
+           break;
+       case ATTR_TYPE_HASH:
+           if ((ch = attr_scan0_string(fp, str_buf,
+                                       "input attribute value")) < 0)
+               return (-1);
+           if (htable_locate(hash_table, STR(name_buf)) != 0) {
+               if ((flags & ATTR_FLAG_EXTRA) != 0) {
+                   msg_warn("duplicate attribute %s in input from %s",
+                            STR(name_buf), VSTREAM_PATH(fp));
+                   return (conversions);
+               }
+           } else {
+               htable_enter(hash_table, STR(name_buf),
+                            mystrdup(STR(str_buf)));
+           }
+           break;
+       default:
+           msg_panic("%s: unknown type code: %d", myname, wanted_type);
+       }
+    }
+}
+
+/* attr_scan0 - read attribute list from stream */
+
+int     attr_scan0(VSTREAM *fp, int flags,...)
+{
+    va_list ap;
+    int     ret;
+
+    va_start(ap, flags);
+    ret = attr_vscan0(fp, flags, ap);
+    va_end(ap);
+    return (ret);
+}
+
+#ifdef TEST
+
+ /*
+  * Proof of concept test program.  Mirror image of the attr_scan0 test
+  * program.
+  */
+#include <msg_vstream.h>
+
+int     var_line_limit = 2048;
+
+int     main(int unused_argc, char **used_argv)
+{
+    VSTRING *str_val = vstring_alloc(1);
+    HTABLE *table = htable_create(1);
+    HTABLE_INFO **ht_info_list;
+    HTABLE_INFO **ht;
+    int     int_val;
+    long    long_val;
+    int     ret;
+
+    msg_verbose = 1;
+    msg_vstream_init(used_argv[0], VSTREAM_ERR);
+    if ((ret = attr_scan0(VSTREAM_IN,
+                         ATTR_FLAG_STRICT,
+                         ATTR_TYPE_NUM, ATTR_NAME_NUM, &int_val,
+                         ATTR_TYPE_LONG, ATTR_NAME_LONG, &long_val,
+                         ATTR_TYPE_STR, ATTR_NAME_STR, str_val,
+                         ATTR_TYPE_HASH, table,
+                         ATTR_TYPE_END)) > 3) {
+       vstream_printf("%s %d\n", ATTR_NAME_NUM, int_val);
+       vstream_printf("%s %ld\n", ATTR_NAME_LONG, long_val);
+       vstream_printf("%s %s\n", ATTR_NAME_STR, STR(str_val));
+       ht_info_list = htable_list(table);
+       for (ht = ht_info_list; *ht; ht++)
+           vstream_printf("(hash) %s %s\n", ht[0]->key, ht[0]->value);
+       myfree((char *) ht_info_list);
+    } else {
+       vstream_printf("return: %d\n", ret);
+    }
+    if ((ret = attr_scan0(VSTREAM_IN,
+                         ATTR_FLAG_STRICT,
+                         ATTR_TYPE_NUM, ATTR_NAME_NUM, &int_val,
+                         ATTR_TYPE_LONG, ATTR_NAME_LONG, &long_val,
+                         ATTR_TYPE_STR, ATTR_NAME_STR, str_val,
+                         ATTR_TYPE_END)) == 3) {
+       vstream_printf("%s %d\n", ATTR_NAME_NUM, int_val);
+       vstream_printf("%s %ld\n", ATTR_NAME_LONG, long_val);
+       vstream_printf("%s %s\n", ATTR_NAME_STR, STR(str_val));
+       ht_info_list = htable_list(table);
+       for (ht = ht_info_list; *ht; ht++)
+           vstream_printf("(hash) %s %s\n", ht[0]->key, ht[0]->value);
+       myfree((char *) ht_info_list);
+    } else {
+       vstream_printf("return: %d\n", ret);
+    }
+    if (vstream_fflush(VSTREAM_OUT) != 0)
+       msg_fatal("write error: %m");
+
+    vstring_free(str_val);
+    htable_free(table, myfree);
+
+    return (0);
+}
+
+#endif
diff --git a/postfix/src/util/attr_scan0.ref b/postfix/src/util/attr_scan0.ref
new file mode 100644 (file)
index 0000000..105382f
--- /dev/null
@@ -0,0 +1,46 @@
+./attr_print0: send attr number = 4711
+./attr_print0: send attr long_number = 1234
+./attr_print0: send attr string = whoopee
+./attr_print0: send attr name foo-name value foo-value
+./attr_print0: send attr name bar-name value bar-value
+./attr_print0: send attr number = 4711
+./attr_print0: send attr long_number = 1234
+./attr_print0: send attr string = whoopee
+./attr_scan0: unknown_stream: wanted attribute: number
+./attr_scan0: input attribute name: number
+./attr_scan0: input attribute value: 4711
+./attr_scan0: unknown_stream: wanted attribute: long_number
+./attr_scan0: input attribute name: long_number
+./attr_scan0: input attribute value: 1234
+./attr_scan0: unknown_stream: wanted attribute: string
+./attr_scan0: input attribute name: string
+./attr_scan0: input attribute value: whoopee
+./attr_scan0: unknown_stream: wanted attribute: (any attribute name or list terminator)
+./attr_scan0: input attribute name: foo-name
+./attr_scan0: input attribute value: foo-value
+./attr_scan0: unknown_stream: wanted attribute: (any attribute name or list terminator)
+./attr_scan0: input attribute name: bar-name
+./attr_scan0: input attribute value: bar-value
+./attr_scan0: unknown_stream: wanted attribute: (any attribute name or list terminator)
+./attr_scan0: input attribute name: (end)
+./attr_scan0: unknown_stream: wanted attribute: number
+./attr_scan0: input attribute name: number
+./attr_scan0: input attribute value: 4711
+./attr_scan0: unknown_stream: wanted attribute: long_number
+./attr_scan0: input attribute name: long_number
+./attr_scan0: input attribute value: 1234
+./attr_scan0: unknown_stream: wanted attribute: string
+./attr_scan0: input attribute name: string
+./attr_scan0: input attribute value: whoopee
+./attr_scan0: unknown_stream: wanted attribute: (list terminator)
+./attr_scan0: input attribute name: (end)
+number 4711
+long_number 1234
+string whoopee
+(hash) foo-name foo-value
+(hash) bar-name bar-value
+number 4711
+long_number 1234
+string whoopee
+(hash) foo-name foo-value
+(hash) bar-name bar-value
similarity index 77%
rename from postfix/src/util/attr_scan.c
rename to postfix/src/util/attr_scan64.c
index 94e4c4ff92413d7caee66b0f425c12cf3c3bf381..786ba483ef5e68d99db529c1d5422200dd8ce343 100644 (file)
@@ -1,27 +1,27 @@
 /*++
 /* NAME
-/*     attr_scan 3
+/*     attr_scan64 3
 /* SUMMARY
 /*     recover attributes from byte stream
 /* SYNOPSIS
 /*     #include <attr.h>
 /*
-/*     int     attr_scan(fp, flags, type, name, ...)
+/*     int     attr_scan64(fp, flags, type, name, ...)
 /*     VSTREAM fp;
 /*     int     flags;
 /*     int     type;
 /*     char    *name;
 /*
-/*     int     attr_vscan(fp, flags, ap)
+/*     int     attr_vscan64(fp, flags, ap)
 /*     VSTREAM fp;
 /*     int     flags;
 /*     va_list ap;
 /* DESCRIPTION
-/*     attr_scan() takes zero or more (name, value) request attributes
+/*     attr_scan64() takes zero or more (name, value) request attributes
 /*     and recovers the attribute values from the byte stream that was
-/*     possibly generated by attr_print().
+/*     possibly generated by attr_print64().
 /*
-/*     attr_vscan() provides an alternative interface that is convenient
+/*     attr_vscan64() provides an alternative interface that is convenient
 /*     for calling from within a variadic function.
 /*
 /*     The input stream is formatted as follows, where (item)* stands
@@ -47,9 +47,9 @@
 /*     characters. The formatting rules aim to make implementations in PERL
 /*     and other languages easy.
 /*
-/*      Normally, attributes must be received in the sequence as specified with 
-/*     the attr_scan() argument list.  The input stream may contain additional
-/*     attributes at any point in the input stream, including additional 
+/*      Normally, attributes must be received in the sequence as specified with
+/*     the attr_scan64() argument list.  The input stream may contain additional
+/*     attributes at any point in the input stream, including additional
 /*     instances of requested attributes.
 /*
 /*     Additional input attributes or input attribute instances are silently
@@ -74,9 +74,9 @@
 /*     case of additional instances of a requested attribute.
 /* .IP ATTR_FLAG_MORE
 /*     After recovering the requested attributes, leave the input stream
-/*     in a state that is usable for more attr_scan() operations from the
+/*     in a state that is usable for more attr_scan64() operations from the
 /*     same input attribute list.
-/*     By default, attr_scan() skips forward past the input attribute list
+/*     By default, attr_scan64() skips forward past the input attribute list
 /*     terminator.
 /* .IP ATTR_FLAG_STRICT
 /*     For convenience, this value combines both ATTR_FLAG_MISSING and
@@ -89,6 +89,8 @@
 /* .RS
 /* .IP "ATTR_TYPE_NUM (char *, int *)"
 /*     This argument is followed by an attribute name and an integer pointer.
+/* .IP "ATTR_TYPE_LONG (char *, long *)"
+/*     This argument is followed by an attribute name and a long pointer.
 /* .IP "ATTR_TYPE_STR (char *, VSTRING *)"
 /*     This argument is followed by an attribute name and a VSTRING pointer.
 /* .IP "ATTR_TYPE_HASH (HTABLE *)"
 /*     untrusted sources. This is unsafe, unless the resulting table is
 /*     queried only with known to be good attribute names.
 /* DIAGNOSTICS
-/*     attr_scan() and attr_vscan() return -1 when malformed input is
+/*     attr_scan64() and attr_vscan64() return -1 when malformed input is
 /*     detected (string too long, incomplete line, missing end marker).
 /*     Otherwise, the result value is the number of attributes that were
 /*     successfully recovered from the input stream (a hash table counts
 /*
 /*     Panic: interface violation. All system call errors are fatal.
 /* SEE ALSO
-/*     attr_print(3) send attributes over byte stream.
+/*     attr_print64(3) send attributes over byte stream.
 /* LICENSE
 /* .ad
 /* .fi
 #define STR(x) vstring_str(x)
 #define LEN(x) VSTRING_LEN(x)
 
-/* attr_scan_string - pull a string from the input stream */
+/* attr_scan64_string - pull a string from the input stream */
 
-static int attr_scan_string(VSTREAM *fp, VSTRING *plain_buf, const char *context)
+static int attr_scan64_string(VSTREAM *fp, VSTRING *plain_buf, const char *context)
 {
     static VSTRING *base64_buf = 0;
     extern int var_line_limit;         /* XXX */
@@ -191,15 +193,15 @@ static int attr_scan_string(VSTREAM *fp, VSTRING *plain_buf, const char *context
     return (ch);
 }
 
-/* attr_scan_number - pull a number from the input stream */
+/* attr_scan64_number - pull a number from the input stream */
 
-static int attr_scan_number(VSTREAM *fp, unsigned *ptr, VSTRING *str_buf,
-                                   const char *context)
+static int attr_scan64_number(VSTREAM *fp, unsigned *ptr, VSTRING *str_buf,
+                                     const char *context)
 {
     char    junk = 0;
     int     ch;
 
-    if ((ch = attr_scan_string(fp, str_buf, context)) < 0)
+    if ((ch = attr_scan64_string(fp, str_buf, context)) < 0)
        return (-1);
     if (sscanf(STR(str_buf), "%u%c", ptr, &junk) != 1 || junk != 0) {
        msg_warn("malformed numerical data from %s while reading %s: %.100s",
@@ -209,16 +211,36 @@ static int attr_scan_number(VSTREAM *fp, unsigned *ptr, VSTRING *str_buf,
     return (ch);
 }
 
-/* attr_vscan - receive attribute list from stream */
+/* attr_scan64_long_number - pull a number from the input stream */
 
-int     attr_vscan(VSTREAM *fp, int flags, va_list ap)
+static int attr_scan64_long_number(VSTREAM *fp, unsigned long *ptr,
+                                          VSTRING *str_buf,
+                                          const char *context)
 {
-    const char *myname = "attr_scan";
+    char    junk = 0;
+    int     ch;
+
+    if ((ch = attr_scan64_string(fp, str_buf, context)) < 0)
+       return (-1);
+    if (sscanf(STR(str_buf), "%lu%c", ptr, &junk) != 1 || junk != 0) {
+       msg_warn("malformed numerical data from %s while reading %s: %.100s",
+                VSTREAM_PATH(fp), context, STR(str_buf));
+       return (-1);
+    }
+    return (ch);
+}
+
+/* attr_vscan64 - receive attribute list from stream */
+
+int     attr_vscan64(VSTREAM *fp, int flags, va_list ap)
+{
+    const char *myname = "attr_scan64";
     static VSTRING *str_buf = 0;
     static VSTRING *name_buf = 0;
     int     wanted_type = -1;
     char   *wanted_name;
     unsigned int *number;
+    unsigned long *long_number;
     VSTRING *string;
     HTABLE *hash_table;
     int     ch;
@@ -282,7 +304,7 @@ int     attr_vscan(VSTREAM *fp, int flags, va_list ap)
            if (msg_verbose)
                msg_info("%s: wanted attribute: %s",
                         VSTREAM_PATH(fp), wanted_name);
-           if ((ch = attr_scan_string(fp, name_buf,
+           if ((ch = attr_scan64_string(fp, name_buf,
                                    "input attribute name")) == VSTREAM_EOF)
                return (-1);
            if (ch == '\n' && LEN(name_buf) == 0) {
@@ -331,8 +353,24 @@ int     attr_vscan(VSTREAM *fp, int flags, va_list ap)
                return (-1);
            }
            number = va_arg(ap, unsigned int *);
-           if ((ch = attr_scan_number(fp, number, str_buf,
-                                      "input attribute value")) < 0)
+           if ((ch = attr_scan64_number(fp, number, str_buf,
+                                        "input attribute value")) < 0)
+               return (-1);
+           if (ch != '\n') {
+               msg_warn("multiple values for attribute %s from %s",
+                        STR(name_buf), VSTREAM_PATH(fp));
+               return (-1);
+           }
+           break;
+       case ATTR_TYPE_LONG:
+           if (ch != ':') {
+               msg_warn("missing value for number attribute %s from %s",
+                        STR(name_buf), VSTREAM_PATH(fp));
+               return (-1);
+           }
+           long_number = va_arg(ap, unsigned long *);
+           if ((ch = attr_scan64_long_number(fp, long_number, str_buf,
+                                             "input attribute value")) < 0)
                return (-1);
            if (ch != '\n') {
                msg_warn("multiple values for attribute %s from %s",
@@ -347,8 +385,8 @@ int     attr_vscan(VSTREAM *fp, int flags, va_list ap)
                return (-1);
            }
            string = va_arg(ap, VSTRING *);
-           if ((ch = attr_scan_string(fp, string,
-                                      "input attribute value")) < 0)
+           if ((ch = attr_scan64_string(fp, string,
+                                        "input attribute value")) < 0)
                return (-1);
            if (ch != '\n') {
                msg_warn("multiple values for attribute %s from %s",
@@ -362,8 +400,8 @@ int     attr_vscan(VSTREAM *fp, int flags, va_list ap)
                         STR(name_buf), VSTREAM_PATH(fp));
                return (-1);
            }
-           if ((ch = attr_scan_string(fp, str_buf,
-                                      "input attribute value")) < 0)
+           if ((ch = attr_scan64_string(fp, str_buf,
+                                        "input attribute value")) < 0)
                return (-1);
            if (ch != '\n') {
                msg_warn("multiple values for attribute %s from %s",
@@ -387,15 +425,15 @@ int     attr_vscan(VSTREAM *fp, int flags, va_list ap)
     }
 }
 
-/* attr_scan - read attribute list from stream */
+/* attr_scan64 - read attribute list from stream */
 
-int     attr_scan(VSTREAM *fp, int flags,...)
+int     attr_scan64(VSTREAM *fp, int flags,...)
 {
     va_list ap;
     int     ret;
 
     va_start(ap, flags);
-    ret = attr_vscan(fp, flags, ap);
+    ret = attr_vscan64(fp, flags, ap);
     va_end(ap);
     return (ret);
 }
@@ -403,7 +441,7 @@ int     attr_scan(VSTREAM *fp, int flags,...)
 #ifdef TEST
 
  /*
-  * Proof of concept test program.  Mirror image of the attr_scan test
+  * Proof of concept test program.  Mirror image of the attr_scan64 test
   * program.
   */
 #include <msg_vstream.h>
@@ -417,17 +455,20 @@ int     main(int unused_argc, char **used_argv)
     HTABLE_INFO **ht_info_list;
     HTABLE_INFO **ht;
     int     int_val;
+    long    long_val;
     int     ret;
 
     msg_verbose = 1;
     msg_vstream_init(used_argv[0], VSTREAM_ERR);
-    if ((ret = attr_scan(VSTREAM_IN,
-                        ATTR_FLAG_STRICT,
-                        ATTR_TYPE_NUM, ATTR_NAME_NUM, &int_val,
-                        ATTR_TYPE_STR, ATTR_NAME_STR, str_val,
-                        ATTR_TYPE_HASH, table,
-                        ATTR_TYPE_END)) > 2) {
+    if ((ret = attr_scan64(VSTREAM_IN,
+                          ATTR_FLAG_STRICT,
+                          ATTR_TYPE_NUM, ATTR_NAME_NUM, &int_val,
+                          ATTR_TYPE_LONG, ATTR_NAME_LONG, &long_val,
+                          ATTR_TYPE_STR, ATTR_NAME_STR, str_val,
+                          ATTR_TYPE_HASH, table,
+                          ATTR_TYPE_END)) > 3) {
        vstream_printf("%s %d\n", ATTR_NAME_NUM, int_val);
+       vstream_printf("%s %ld\n", ATTR_NAME_LONG, long_val);
        vstream_printf("%s %s\n", ATTR_NAME_STR, STR(str_val));
        ht_info_list = htable_list(table);
        for (ht = ht_info_list; *ht; ht++)
@@ -436,12 +477,14 @@ int     main(int unused_argc, char **used_argv)
     } else {
        vstream_printf("return: %d\n", ret);
     }
-    if ((ret = attr_scan(VSTREAM_IN,
-                        ATTR_FLAG_STRICT,
-                        ATTR_TYPE_NUM, ATTR_NAME_NUM, &int_val,
-                        ATTR_TYPE_STR, ATTR_NAME_STR, str_val,
-                        ATTR_TYPE_END)) == 2) {
+    if ((ret = attr_scan64(VSTREAM_IN,
+                          ATTR_FLAG_STRICT,
+                          ATTR_TYPE_NUM, ATTR_NAME_NUM, &int_val,
+                          ATTR_TYPE_LONG, ATTR_NAME_LONG, &long_val,
+                          ATTR_TYPE_STR, ATTR_NAME_STR, str_val,
+                          ATTR_TYPE_END)) == 3) {
        vstream_printf("%s %d\n", ATTR_NAME_NUM, int_val);
+       vstream_printf("%s %ld\n", ATTR_NAME_LONG, long_val);
        vstream_printf("%s %s\n", ATTR_NAME_STR, STR(str_val));
        ht_info_list = htable_list(table);
        for (ht = ht_info_list; *ht; ht++)
diff --git a/postfix/src/util/attr_scan64.ref b/postfix/src/util/attr_scan64.ref
new file mode 100644 (file)
index 0000000..1b3a015
--- /dev/null
@@ -0,0 +1,46 @@
+./attr_print64: send attr number = 4711
+./attr_print64: send attr long_number = 1234
+./attr_print64: send attr string = whoopee
+./attr_print64: send attr name foo-name value foo-value
+./attr_print64: send attr name bar-name value bar-value
+./attr_print64: send attr number = 4711
+./attr_print64: send attr long_number = 1234
+./attr_print64: send attr string = whoopee
+./attr_scan64: unknown_stream: wanted attribute: number
+./attr_scan64: input attribute name: number
+./attr_scan64: input attribute value: 4711
+./attr_scan64: unknown_stream: wanted attribute: long_number
+./attr_scan64: input attribute name: long_number
+./attr_scan64: input attribute value: 1234
+./attr_scan64: unknown_stream: wanted attribute: string
+./attr_scan64: input attribute name: string
+./attr_scan64: input attribute value: whoopee
+./attr_scan64: unknown_stream: wanted attribute: (any attribute name or list terminator)
+./attr_scan64: input attribute name: foo-name
+./attr_scan64: input attribute value: foo-value
+./attr_scan64: unknown_stream: wanted attribute: (any attribute name or list terminator)
+./attr_scan64: input attribute name: bar-name
+./attr_scan64: input attribute value: bar-value
+./attr_scan64: unknown_stream: wanted attribute: (any attribute name or list terminator)
+./attr_scan64: input attribute name: (end)
+./attr_scan64: unknown_stream: wanted attribute: number
+./attr_scan64: input attribute name: number
+./attr_scan64: input attribute value: 4711
+./attr_scan64: unknown_stream: wanted attribute: long_number
+./attr_scan64: input attribute name: long_number
+./attr_scan64: input attribute value: 1234
+./attr_scan64: unknown_stream: wanted attribute: string
+./attr_scan64: input attribute name: string
+./attr_scan64: input attribute value: whoopee
+./attr_scan64: unknown_stream: wanted attribute: (list terminator)
+./attr_scan64: input attribute name: (end)
+number 4711
+long_number 1234
+string whoopee
+(hash) foo-name foo-value
+(hash) bar-name bar-value
+number 4711
+long_number 1234
+string whoopee
+(hash) foo-name foo-value
+(hash) bar-name bar-value
index 980c22df13961483e6fb80a4fe9d5a69b8911996..dddbcb62aace1cd62c044adf72ebbebf7ca53416 100644 (file)
@@ -107,6 +107,7 @@ int     inet_trigger(const char *service, const char *buf, int len, int timeout)
            msg_warn("%s: connect to %s: %m", myname, service);
        return (-1);
     }
+    close_on_exec(fd, CLOSE_ON_EXEC);
     ip = (struct inet_trigger *) mymalloc(sizeof(*ip));
     ip->fd = fd;
     ip->service = mystrdup(service);
index 7da0f297db022e0f913aff5deeaa75ad43fe8e52..ac9681b1d0fed6a46c1f08631c72f1319f573bc6 100644 (file)
@@ -29,6 +29,9 @@ extern int timed_write(int, void *, unsigned, int, void *);
 extern void doze(unsigned);
 extern void rand_sleep(unsigned, unsigned);
 extern int duplex_pipe(int *);
+extern int sock_empty_wait(int, int);
+extern int sock_maximize_send_lowat(int);
+extern void sock_set_send_lowat(int, int);
 
 #define BLOCKING       0
 #define NON_BLOCKING   1
index 31efea03ed40ad88f52e5a05d86ee23ca4114b78..ad1b451de701371aa2ebbc1c029403cd1b62644a 100644 (file)
@@ -54,7 +54,7 @@ int     make_dirs(const char *path, int perms)
     int     saved_ch;
     struct stat st;
     int     ret;
-    mode_t  saved_mode;
+    mode_t  saved_mode = 0;
 
     /*
      * Initialize. Make a copy of the path that we can safely clobber.
index 7ae42d6d503e5d5c502bcf41a99fd3a42d76dd4e..3d9e71c3f00dcdf1eeb77406b3e8f573ba40cb78 100644 (file)
@@ -6,10 +6,11 @@
 /* SYNOPSIS
 /*     #include <match_list.h>
 /*
-/*     MATCH_LIST *match_list_init(pattern_list, count, func,...)
+/*     MATCH_LIST *match_list_init(flags, pattern_list, count, func,...)
+/*     int     flags;
 /*     const char *pattern_list;
 /*     int     count;
-/*     int     (*func)(const char *string, const char *pattern);
+/*     int     (*func)(int flags, const char *string, const char *pattern);
 /*
 /*     int     match_list_match(list, string,...)
 /*     MATCH_LIST *list;
 /*     a pattern match, precede a non-file name pattern with an
 /*     exclamation point (!).
 /*
-/*     match_list_init() performs initializations. The first argument is
-/*     a list of patterns.  The second argument specifies how many match
-/*     functions follow.
+/*     match_list_init() performs initializations. The flags argument
+/*     specifies the bit-wise OR of zero or more of the following:
+/* .RS
+/* .IP MATCH_FLAG_PARENT
+/*     The hostname pattern foo.com matches any name within the domain
+/*     foo.com. If this flag is cleared, foo.com matches itself
+/*     only, and .foo.com matches any name below the domain foo.com.
+/* .RE
+/*     Specify MATCH_FLAG_NONE to request none of the above.
+/*     The pattern_list argument specifies a list of patterns.  The third
+/*     argument specifies how many match functions follow.
 /*
 /*     match_list_match() matches strings against the specified pattern
 /*     list, passing the first string to the first function given to
 #include <stringops.h>
 #include <argv.h>
 #include <dict.h>
+#include <match_ops.h>
 #include <match_list.h>
 
 /* Application-specific */
 
 struct MATCH_LIST {
+    int     flags;                     /* processing options */
     ARGV   *patterns;                  /* one pattern each */
     int     match_count;               /* match function/argument count */
     MATCH_LIST_FN *match_func;         /* match functions */
@@ -125,14 +136,18 @@ static ARGV *match_list_parse(ARGV *list, char *string)
 
 /* match_list_init - initialize pattern list */
 
-MATCH_LIST *match_list_init(const char *patterns, int match_count,...)
+MATCH_LIST *match_list_init(int flags, const char *patterns, int match_count,...)
 {
     MATCH_LIST *list;
     char   *saved_patterns;
     va_list ap;
     int     i;
 
+    if (flags & ~MATCH_FLAG_ALL)
+       msg_panic("match_list_init: bad flags 0x%x", flags);
+
     list = (MATCH_LIST *) mymalloc(sizeof(*list));
+    list->flags = flags;
     list->match_count = match_count;
     list->match_func =
        (MATCH_LIST_FN *) mymalloc(match_count * sizeof(MATCH_LIST_FN));
@@ -173,7 +188,7 @@ int     match_list_match(MATCH_LIST * list,...)
        for (match = 1; *pat == '!'; pat++)
            match = !match;
        for (i = 0; i < list->match_count; i++)
-           if (list->match_func[i] (list->match_args[i], pat) != 0)
+           if (list->match_func[i] (list->flags, list->match_args[i], pat))
                return (match);
     }
     if (msg_verbose)
index aba88b8f6941cbb82444fddb8cb21c27c3693838..910ae713bf2698557427bc266344f3d73499dbd7 100644 (file)
@@ -15,9 +15,9 @@
   * External interface.
   */
 typedef struct MATCH_LIST MATCH_LIST;
-typedef int (*MATCH_LIST_FN) (const char *, const char *);
+typedef int (*MATCH_LIST_FN) (int, const char *, const char *);
 
-extern MATCH_LIST *match_list_init(const char *, int,...);
+extern MATCH_LIST *match_list_init(int, const char *, int,...);
 extern int match_list_match(MATCH_LIST *,...);
 extern void match_list_free(MATCH_LIST *);
 
index 764866bbc1ce6b6a178f73972a9365037093a186..1bde84abdfa463aabd0115b48c78d0448a9c4037 100644 (file)
@@ -6,15 +6,18 @@
 /* SYNOPSIS
 /*     #include <match_ops.h>
 /*
-/*     int     match_string(string, pattern)
+/*     int     match_string(flags, string, pattern)
+/*     int     flags;
 /*     const char *string;
 /*     const char *pattern;
 /*
-/*     int     match_hostname(name, pattern)
+/*     int     match_hostname(flags, name, pattern)
+/*     int     flags;
 /*     const char *name;
 /*     const char *pattern;
 /*
-/*     int     match_hostaddr(addr, pattern)
+/*     int     match_hostaddr(flags, addr, pattern)
+/*     int     flags;
 /*     const char *addr;
 /*     const char *pattern;
 /* DESCRIPTION
 /*     or address comparison.
 /*
 /*     match_string() matches the string against the pattern, requiring
-/*     an exact (case-insensitive) match.
+/*     an exact (case-insensitive) match. The flags argument is not used.
 /*
 /*     match_hostname() matches the host name when the hostname matches
 /*     the pattern exactly, or when the pattern matches a parent domain
-/*     of the named host.
+/*     of the named host. The flags argument specifies the bit-wise OR
+/*     of zero or more of the following:
+/* .IP MATCH_FLAG_PARENT
+/*     The hostname pattern foo.com matches itself and any name below
+/*     the domain foo.com. If this flag is cleared, foo.com matches itself
+/*     only, and .foo.com matches any name below the domain foo.com.
+/* .RE
+/*     Specify MATCH_FLAG_NONE to request none of the above.
 /*
 /*     match_hostaddr() matches a host address when the pattern is
 /*     identical to the host address, or when the pattern is a net/mask
 /*     that contains the address. The mask specifies the number of
-/*     bits in the network part of the pattern.
+/*     bits in the network part of the pattern. The flags argument is
+/*     not used.
 /* LICENSE
 /* .ad
 /* .fi
@@ -72,7 +83,7 @@
 
 /* match_string - match a string literal */
 
-int     match_string(const char *string, const char *pattern)
+int     match_string(int unused_flags, const char *string, const char *pattern)
 {
     char   *myname = "match_string";
     int     match;
@@ -110,7 +121,7 @@ int     match_string(const char *string, const char *pattern)
 
 /* match_hostname - match a host by name */
 
-int     match_hostname(const char *name, const char *pattern)
+int     match_hostname(int flags, const char *name, const char *pattern)
 {
     char   *myname = "match_hostname";
     const char *pd;
@@ -128,13 +139,15 @@ int     match_hostname(const char *name, const char *pattern)
     if (strchr(pattern, ':') != 0) {
        temp = lowercase(mystrdup(name));
        match = 0;
-       for (entry = temp; /* void */ ; entry = next + 1) {
+       for (entry = temp; /* void */ ; entry = next) {
            if ((match = (dict_lookup(pattern, entry) != 0)) != 0)
                break;
            if (dict_errno != 0)
                msg_fatal("%s: table lookup problem", pattern);
-           if ((next = strchr(entry, '.')) == 0)
+           if ((next = strchr(entry + 1, '.')) == 0)
                break;
+           if (flags & MATCH_FLAG_PARENT)
+               next += 1;
        }
        myfree(temp);
        return (match);
@@ -151,9 +164,15 @@ int     match_hostname(const char *name, const char *pattern)
      * See if the pattern is a parent domain of the hostname.
      */
     else {
-       pd = name + strlen(name) - strlen(pattern);
-       if (pd > name && pd[-1] == '.' && strcasecmp(pd, pattern) == 0)
-           return (1);
+       if (flags & MATCH_FLAG_PARENT) {
+           pd = name + strlen(name) - strlen(pattern);
+           if (pd > name && pd[-1] == '.' && strcasecmp(pd, pattern) == 0)
+               return (1);
+       } else if (pattern[0] == '.') {
+           pd = name + strlen(name) - strlen(pattern);
+           if (pd > name && strcasecmp(pd, pattern) == 0)
+               return (1);
+       }
     }
     return (0);
 }
@@ -181,7 +200,7 @@ static int match_parse_mask(const char *pattern, unsigned long *net_bits,
 
 /* match_hostaddr - match host by address */
 
-int     match_hostaddr(const char *addr, const char *pattern)
+int     match_hostaddr(int unused_flags, const char *addr, const char *pattern)
 {
     char   *myname = "match_hostaddr";
     int     mask_shift;
index a938c04fb34a5bd9745f301258a49eb5e381b5fc..e147f7b50dd1308df426e14d5143c8cf20d50a3d 100644 (file)
 
  /* External interface. */
 
-extern int match_string(const char *, const char *);
-extern int match_hostname(const char *, const char *);
-extern int match_hostaddr(const char *, const char *);
+#define MATCH_FLAG_NONE                0
+#define MATCH_FLAG_PARENT      (1<<0)
+#define MATCH_FLAG_ALL         (MATCH_FLAG_PARENT)
+
+extern int match_string(int, const char *, const char *);
+extern int match_hostname(int, const char *, const char *);
+extern int match_hostaddr(int, const char *, const char *);
 
 /* LICENSE
 /* .ad
diff --git a/postfix/src/util/sock_empty_wait.c b/postfix/src/util/sock_empty_wait.c
new file mode 100644 (file)
index 0000000..8cc6819
--- /dev/null
@@ -0,0 +1,207 @@
+/*++
+/* NAME
+/*     sock_empty_wait 3
+/* SUMMARY
+/*     wait until socket send buffer is near empty
+/* SYNOPSIS
+/*     #include <iostuff.h>
+/*
+/*     int     sock_empty_wait(fd, timeout)
+/*     int     fd;
+/*     int     timeout;
+/* AUXILIARY ROUTINES
+/*     int     sock_maximize_send_lowat(fd)
+/*     int     fd;
+/*
+/*     void    sock_set_send_lowat(fd, send_lowat)
+/*     int     fd;
+/*     int     send_lowat;
+/* DESCRIPTION
+/*     sock_empty_wait() blocks the process until the specified socket's
+/*     send buffer is near empty, in the hope that the contents of the
+/*     next write() operation will not be merged with preceding data.
+/*
+/*     sock_maximize_send_lowat() maximizes the socket send buffer
+/*     low-water mark, which controls how much free buffer space must
+/*     be available before the socket is considered writable.
+/*     The result value is the old low-water mark value.
+/*
+/*     sock_set_send_lowat() sets the socket send buffer low-water mark
+/*     to the specified value.
+/*
+/*     Arguments:
+/* .IP fd
+/*     File descriptor in the range 0..FD_SETSIZE.
+/* .IP timeout
+/*     If positive, deadline in seconds. A zero value effects a poll.
+/*     A negative value means wait until something happens.
+/* DIAGNOSTICS
+/*     sock_maximize_send_lowat() returns -1 if the kernel does not
+/*     support access to or control over the send buffer low-water mark.
+/*     Otherwise, all system call errors are fatal.
+/*
+/*     A zero result means success.  When the specified deadline is
+/*     exceeded, sock_empty_wait() returns -1 and sets errno to ETIMEDOUT.
+/* BUGS
+/*     Linux and Solaris do not provide the necessary support. Until
+/*     they become better citizens they are punished by having to sleep
+/*     for 10 seconds, and even then there is no reasonable way to find
+/*     out if all the written data was acknowledged by the remote TCP.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <iostuff.h>
+
+/* sock_maximize_send_lowat - maximize the send buffer low-water mark */
+
+int     sock_maximize_send_lowat(int fd)
+{
+    char   *myname = "sock_maximize_send_lowat";
+    int     send_buffer_size;
+    int     saved_low_water_mark;
+    int     want_low_water_mark;
+    int     got_low_water_mark;
+    SOCKOPT_SIZE optlen;
+
+    /*
+     * Get the send buffer size. If this succeeds then we know the file
+     * handle is a socket.
+     */
+    optlen = sizeof(send_buffer_size);
+    if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF,
+                  (char *) &send_buffer_size, &optlen) < 0)
+       msg_fatal("%s: getsockopt SO_SNDBUF: %m", myname);
+
+    /*
+     * Save the send buffer low-water mark. XXX Solaris 8 does not support
+     * this operation.
+     */
+    optlen = sizeof(saved_low_water_mark);
+    if (getsockopt(fd, SOL_SOCKET, SO_SNDLOWAT,
+                  (char *) &saved_low_water_mark, &optlen) < 0) {
+       if (msg_verbose)
+           msg_info("%s: getsockopt SO_SNDLOWAT: %m", myname);
+       return (-1);
+    }
+
+    /*
+     * Max out the send buffer low-water mark. XXX Linux 2.4.14 does not
+     * support this operation.
+     */
+    want_low_water_mark = send_buffer_size;
+    if (setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT,
+                  (char *) &want_low_water_mark,
+                  sizeof(want_low_water_mark)) < 0) {
+       if (msg_verbose)
+           msg_info("%s: setsockopt SO_SNDLOWAT: %m", myname);
+       return (-1);
+    }
+
+    /*
+     * Make sure the kernel did not cheat.
+     */
+    optlen = sizeof(got_low_water_mark);
+    if (getsockopt(fd, SOL_SOCKET, SO_SNDLOWAT,
+                  (char *) &got_low_water_mark, &optlen) < 0)
+       msg_fatal("%s: getsockopt SO_SNDLOWAT: %m", myname);
+    if (got_low_water_mark == 1)
+       return (-1);
+
+    /*
+     * Make debugging a bit easier.
+     */
+    if (msg_verbose) {
+       msg_info("%s: send buffer %d, low-water mark was %d, wanted %d, got %d",
+                myname, send_buffer_size, saved_low_water_mark,
+                want_low_water_mark, got_low_water_mark);
+
+    }
+    return (saved_low_water_mark);
+}
+
+/* sock_set_send_lowat - restore socket send buffer low-water mark */
+
+void    sock_set_send_lowat(int fd, int want_low_water_mark)
+{
+    char   *myname = "sock_set_send_lowat";
+    int     got_low_water_mark;
+    SOCKOPT_SIZE optlen;
+
+    /*
+     * Set the send buffer low-water mark.
+     */
+    if (setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT,
+                  (char *) &want_low_water_mark,
+                  sizeof(want_low_water_mark)) < 0)
+       msg_fatal("%s: setsockopt SO_SNDLOWAT: %m", myname);
+
+    /*
+     * Make debugging a bit easier.
+     */
+    if (msg_verbose) {
+       optlen = sizeof(got_low_water_mark);
+       if (getsockopt(fd, SOL_SOCKET, SO_SNDLOWAT,
+                      (char *) &got_low_water_mark, &optlen) < 0)
+           msg_fatal("%s: getsockopt SO_SNDLOWAT: %m", myname);
+       msg_info("%s: low-water mark wanted %d, got %d",
+                myname, want_low_water_mark, got_low_water_mark);
+    }
+}
+
+/* sock_empty_wait - wait until socket send buffer is near empty */
+
+int     sock_empty_wait(int fd, int timeout)
+{
+    int     saved_errno;
+    int     saved_low_water_mark;
+    int     result;
+
+    /*
+     * Max out the send buffer low-water mark.
+     */
+    saved_low_water_mark = sock_maximize_send_lowat(fd);
+
+    /*
+     * Wait until the socket is considered writable.
+     */
+    result = write_wait(fd, timeout);
+
+    /*
+     * Work around systems that have no functional SO_SNDLOWAT control.
+     */
+    if (result == 0 && saved_low_water_mark <= 0)
+       sleep(10);
+
+    /*
+     * Restore the send buffer low-water mark.
+     */
+    if (saved_low_water_mark > 0) {
+       saved_errno = errno;
+       sock_set_send_lowat(fd, saved_low_water_mark);
+       errno = saved_errno;
+    }
+
+    /*
+     * Done.
+     */
+    return (result);
+}
index 31b4dae0a01bddec1c13377e72d5d2aade85a807..9cb57e5135ecbe34f86253f42f26ca78559cc6de 100644 (file)
@@ -103,6 +103,7 @@ int     stream_trigger(const char *service, const char *buf, int len, int timeou
            msg_warn("%s: connect to %s: %m", myname, service);
        return (-1);
     }
+    close_on_exec(fd, CLOSE_ON_EXEC);
 
     /*
      * Stash away context.
index d4a341d75800c58b75d46de1f35bda018d410ac3..6a3b1916073b3b862a6a3b3525d18b80e2c60cde 100644 (file)
@@ -104,6 +104,7 @@ int     unix_trigger(const char *service, const char *buf, int len, int timeout)
            msg_warn("%s: connect to %s: %m", myname, service);
        return (-1);
     }
+    close_on_exec(fd, CLOSE_ON_EXEC);
 
     /*
      * Stash away context.
index 078d255e1ac28ebf137cee2263e4a440b109d807..2f644bf1dc7f994310a49c280dac302ffe942031 100644 (file)
 /*     VSTRING *vp;
 /*     VSTREAM *fp;
 /*     int     bound;
+/*
+/*     int     vstring_get_null_bound(vp, fp, bound)
+/*     VSTRING *vp;
+/*     VSTREAM *fp;
+/*     int     bound;
 /* DESCRIPTION
 /*     The routines in this module each read one newline or null-terminated
 /*     string from an input stream. In all cases the result is either the
@@ -41,7 +46,7 @@
 /*     vstring_get_null() reads a null-terminated string from the named
 /*     stream.
 /*
-/*     vstring_get_bound() and vstring_get_nonl_bound() read no more
+/*     the vstring_get<whatever>_bound() routines read no more
 /*     than \fIbound\fR characters.  Otherwise they behave like the
 /*     unbounded versions documented above.
 /* DIAGNOSTICS
@@ -154,6 +159,22 @@ int     vstring_get_nonl_bound(VSTRING *vp, VSTREAM *fp, int bound)
     return (c == '\n' ? c : VSTRING_GET_RESULT(vp));
 }
 
+/* vstring_get_null_bound - read null-terminated string from file */
+
+int     vstring_get_null_bound(VSTRING *vp, VSTREAM *fp, int bound)
+{
+    int     c;
+
+    if (bound <= 0)
+       msg_panic("vstring_get_nonl_bound: invalid bound %d", bound);
+
+    VSTRING_RESET(vp);
+    while (bound-- > 0 && (c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != 0)
+       VSTRING_ADDCH(vp, c);
+    VSTRING_TERMINATE(vp);
+    return (c == 0 ? c : VSTRING_GET_RESULT(vp));
+}
+
 #ifdef TEST
 
  /*
index 897167ca6402317eb226f0f2cfb2d905ed70b506..68bd8106db0c57e913cc963b0f4c83ccebb8369d 100644 (file)
@@ -24,6 +24,7 @@ extern int vstring_get_nonl(VSTRING *, VSTREAM *);
 extern int vstring_get_null(VSTRING *, VSTREAM *);
 extern int vstring_get_bound(VSTRING *, VSTREAM *, int);
 extern int vstring_get_nonl_bound(VSTRING *, VSTREAM *, int);
+extern int vstring_get_null_bound(VSTRING *, VSTREAM *, int);
 
  /*
   * Backwards compatibility for code that still uses the vstring_fgets()
index 14c388e8aa195619d953762636ee7a34475df8a8..7968dcc2856590ceca26c6f9b01d4a6cd3571d86 100644 (file)
 /*     numerical user ID values that may be specified in any
 /*     \fBvirtual_owner_maps\fR or \fBvirtual_uid_maps\fR.
 /* SECURITY
+/* .ad
+/* .fi
 /*     The virtual delivery agent is not security sensitive, provided
-/*     that the lookup tables with recipient information are adequately
-/*     protected. This program is not designed to run chrooted.
+/*     that the lookup tables with recipient user/group ID information are
+/*     adequately protected. This program is not designed to run chrooted.
 /* STANDARDS
 /*     RFC 822 (ARPA Internet Text Messages)
 /* DIAGNOSTICS
 /*     This setting is ignored with \fBmaildir\fR style delivery,
 /*     because such deliveries are safe without explicit locks.
 /*
-/*     Use the command \fBpostconf -m\fR to find out what locking methods
+/*     Use the command \fBpostconf -l\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