diff --git a/postfix/HISTORY b/postfix/HISTORY index 147acda81..b2ede1bab 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -3515,3 +3515,31 @@ Apologies for any names omitted. to enable LMTP delivery over UNIX-domain sockets. The goal is to simplify the experimental LMTP delivery agent by ripping out the privileged code that forks the LMTP server. + +20000102 + + Clarified documentation after early feedback on the 19991231 + release by Drew Derbyshire, Ollivier Robert, Khetan Gajjar. + + Sanity check: a common error is to list Postfix virtual + domains in the mydestination parameter. This causes the + new optional local_recipient_maps feature to reject mail + for virtual users. The SMTP server now explicitly tests + for this common error and logs a warning instead of refusing + the mail. File: smtpd/smtpd_check.c. + +20000104 + + Bugfix: a case sensitivity bug had slipped through in the + anti-relaying code, causing mail for USER@VIRTUAL.DOMAIN + to be rejected with "relay access denied". This was found + by Jim Maenpaa @ jmm.com. + + Questionable feature: set "smtp_skip_5xx_greeting = yes" + to make Postfix more sendmail compatible, even though this + is wrong, IMNSHO. File: smtp/smtp_connect.c. + + Portability: Ultrix patch from Simon Burge @ thistledown.com.au. + + Portability: Siemens Pyramid (dcosx) patch by Thomas D. + Knox @ vushta.com. diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 02eb24fa9..29ee8f20b 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -1,3 +1,14 @@ +Incompatible changes with snapshot-20000104 +=========================================== + +None sofar. + +Major changes with snapshot-20000104 +==================================== + +Questionable feature: with "smtp_skip_5xx_greeting = yes", Postfix +emulates brain damage found in some other MTAs. + Incompatible changes with postfix-19991231: =========================================== @@ -76,10 +87,10 @@ installation can be done without write access to the build tree. - The SMTP server now rejects mail for unknown users in virtual domains that are defined by Postfix virtual maps. -- The SMTP server optionally rejects mail for unknown local users. -Use "local_recipient_maps = $alias_maps, unix:passwd.byname" if -your local mail is delivered by a UNIX-style local delivery agent. -See example in conf/main.cf. +- The SMTP server can reject mail for unknown local users. Specify +"local_recipient_maps = $relocated_maps, $alias_maps, unix:passwd.byname" +if your local mail is delivered by a UNIX-style local delivery +agent. See example in conf/main.cf. - Use "disable_vrfy_command = yes" to disable the SMTP VRFY command. This prevents some forms of address harvesting. diff --git a/postfix/conf/access b/postfix/conf/access index f4ca6ea31..ba45f0d2e 100644 --- a/postfix/conf/access +++ b/postfix/conf/access @@ -10,12 +10,21 @@ # to selectively reject or accept mail from or to specific hosts, # domains, networks, host addresses or mail addresses. # -# The table serves as input to the \fBpostmap\fR(1) command. The -# result, an indexed file in \fBdbm\fR or \fBdb\fR format, +# Normally, the table serves as input to the \fBpostmap\fR(1) command. +# The result, an indexed file in \fBdbm\fR or \fBdb\fR format, # is used for fast searching by the mail system. After an update # it may take a minute or so before the change becomes visible. # Issue a \fBpostfix reload\fR command to eliminate the delay. # +# When the table is provided via other means such as NIS, LDAP +# or SQL, the same lookups are done as for ordinary indexed files. +# +# Alternatively, the table can be provided as a regular-expression +# map where patterns are given as regular expressions. In that case, +# the lookups are done in a slightly different way as described below. +# TABLE FORMAT +# .ad +# .fi # The format of the access table is as follows: # .IP "blanks and comments" # Blank lines are ignored, as are lines beginning with `#'. @@ -23,14 +32,15 @@ # When \fIpattern\fR matches a mail address, domain or host address, # perform the corresponding \fIaction\fR. # PATTERNS -# Patterns are tried in the order as listed below: # .ad # .fi +# With lookups from indexed files, patterns are tried in the order as +# listed below: # .IP \fIuser\fR@\fIdomain\fR # Matches the specified mail address. # .IP \fIdomain.name\fR -# Matches the \fIdomain.name\fR itself and any subdomain thereof, -# either in hostnames or in mail addresses. Top-level domains will +# Matches the \fIdomain.name\fR itself and any subdomain thereof, +# either in hostnames or in mail addresses. Top-level domains will # never be matched. # .IP \fIuser\fR@ # Matches all mail addresses with the specified user part. @@ -52,11 +62,34 @@ # .IP \fBOK\fR # .IP "\fIAny other text\fR" # Accept the address etc. that matches the pattern. +# REGULAR EXPRESSION TABLES +# .ad +# .fi +# This section describes how the table lookups change when the table +# is given in the form of regular expressions. For a description of +# regular expression lookup table syntax, see \fBregexp_table\fR(5) +# or \fBpcre_table\fR(5). +# +# Patterns become regular expressions that are applied to the entire +# string being looked up. Depending on the application, that string +# is an entire client hostname, an entire client IP address, or an +# entire mail address. +# +# In contrast to the normal lookups from indexed files, no parent +# domain or network search is done, and \fIuser@domain\fR mail +# addresses are not broken up into their \fIuser@\fR and \fIdomain\fR +# constituent parts. +# +# Actions are the same as with normal indexed file lookups, with +# the additional feature that parenthesized substrings from the +# pattern can be interpolated as \fB$1\fR, \fB$2\fR and so on. # BUGS # The table format does not understand quoting conventions. # SEE ALSO # postmap(1) create mapping table # smtpd(8) smtp server +# pcre_table(5) format of PCRE tables +# regexp_table(5) format of POSIX regexp tables # LICENSE # .ad # .fi diff --git a/postfix/conf/main.cf b/postfix/conf/main.cf index 538eb04e9..0eeb4e4b0 100644 --- a/postfix/conf/main.cf +++ b/postfix/conf/main.cf @@ -125,7 +125,10 @@ mail_owner = postfix # Beware: if the Postfix SMTP server runs chrooted, you may have to # copy the passwd database into the jail. This is system dependent. # -#local_recipient_maps = $alias_maps unix:passwd.byname +# FOR THIS TO WORK, DO NOT SPECIFY VIRTUAL DOMAINS IN MYDESTINATION. +# MYDESTINATION MUST LIST NON-VIRTUAL DOMAINS ONLY. +# +#local_recipient_maps = $relocated_maps $alias_maps unix:passwd.byname # ADDRESS REWRITING # diff --git a/postfix/global/mail_params.h b/postfix/global/mail_params.h index d01ad5977..508acbf02 100644 --- a/postfix/global/mail_params.h +++ b/postfix/global/mail_params.h @@ -576,6 +576,10 @@ extern int var_smtp_quit_tmout; #define DEF_SMTP_SKIP_4XX 0 extern bool var_smtp_skip_4xx_greeting; +#define VAR_SMTP_SKIP_5XX "smtp_skip_5xx_greeting" +#define DEF_SMTP_SKIP_5XX 0 +extern bool var_smtp_skip_5xx_greeting; + #define VAR_IGN_MX_LOOKUP_ERR "ignore_mx_lookup_error" #define DEF_IGN_MX_LOOKUP_ERR 0 extern bool var_ign_mx_lookup_err; diff --git a/postfix/global/mail_version.h b/postfix/global/mail_version.h index 9bce34df4..dc50b79d4 100644 --- a/postfix/global/mail_version.h +++ b/postfix/global/mail_version.h @@ -15,7 +15,7 @@ * Version of this program. */ #define VAR_MAIL_VERSION "mail_version" -#define DEF_MAIL_VERSION "Postfix-19991231" +#define DEF_MAIL_VERSION "Snapshot-20000104" extern char *var_mail_version; /* LICENSE diff --git a/postfix/html/faq.html b/postfix/html/faq.html index fd4cce913..50bfd4f29 100644 --- a/postfix/html/faq.html +++ b/postfix/html/faq.html @@ -28,9 +28,9 @@
  • Mail relaying -
  • Delivery to remote systems +
  • Remote delivery -
  • Delivery to local (non-virtual) addresses +
  • Local (non-virtual) delivery
  • Mailing lists @@ -87,6 +87,8 @@ distribution list
  • Postfix breaks the majordomo "approve" command +
  • Postfix does not try all the MX addresses +

    Mail relaying

    @@ -97,22 +99,24 @@ distribution list
  • Relaying mail for mobile users -
  • Postfix refuses to receive mail for some -virtual domains +
  • Postfix refuses mail for virtual +domains with "relay access denied"
  • Restricting what users can send mail to off-site destinations -

    Delivery to remote systems

    +

    Remote delivery

    -

    Delivery to local (non-virtual) addresses

    +

    Local (non-virtual) delivery

    @@ -234,7 +250,7 @@ needs tweaking only if you have a very slow or a very fast net/machine. Workstation:
    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             myorigin = $mydomain
     
    @@ -242,7 +258,7 @@ Workstation: Server:
    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             myorigin = $mydomain
             mydestination = $myhostname, localhost.$mydomain, $mydomain
     
    @@ -259,7 +275,7 @@ workstation: Server:
    -    /etc/aliases:
    +    /etc/aliases:
             joe:    joe@joes.workstation
             jane:   jane@janes.workstation
     
    @@ -287,11 +303,11 @@ domain.

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             myorigin = $mydomain
             relayhost = $mydomain
     
    -    /etc/postfix/master.cf:
    +    /etc/postfix/master.cf:
             Comment out the SMTP server entry
             Comment out the local delivery agent entry
     
    @@ -318,7 +334,7 @@ to let that mail gateway take care of forwarding. because it allows users to change machines without hassle.
    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             myorigin = $mydomain
     
    @@ -330,7 +346,7 @@ for mail for the local machine:

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             relayhost = $mydomain
     
    @@ -347,7 +363,7 @@ specify the intranet mail gateway host itself:

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             relayhost = host.my.domain
     
    @@ -359,7 +375,7 @@ DNS lookups as well:

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             disable_dns_lookups = yes
     
    @@ -378,13 +394,13 @@ href="transport.5.html">transport table lookups.

    -    /etc/postfix/transport:
    +    /etc/postfix/transport:
             my.domain               smtp:
             .my.domain              smtp:
    -        thishost.my.domain      local:        !important!
    -        localhost.my.domain     local:        !important!
    +        thishost.my.domain      local:        !!!important!!!
    +        localhost.my.domain     local:        !!!important!!!
     
    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             transport_maps = hash:/etc/postfix/transport
     
    @@ -395,8 +411,9 @@ else mail will bounce with a "mail loops to myself" condition.

    -Specify dbm:/etc/postfix/transport if your system -uses dbm files instead of db. +Specify dbm:/etc/postfix/transport if your system uses +dbm files instead of db. To find out what map types +Postfix supports, use the command postconf -m.

    @@ -438,23 +455,24 @@ route mail for my.domain to the inside machine:

    -/etc/postfix/main.cf:
    +/etc/postfix/main.cf:
         mydestination = $myhostname, my.domain, localhost.my.domain
         relay_domains =
         transport_maps = hash:/etc/postfix/transport
     
    -/etc/postfix/transport:
    +/etc/postfix/transport:
         my.domain   smtp:inside-gateway.my.domain   (forwards user@domain)
         .my.domain  smtp:inside-gateway.my.domain   (forwards user@firewall)
     
    -/etc/postfix/master.cf:
    +/etc/postfix/master.cf:
         Comment out the local delivery agent
     

    -Specify dbm:/etc/postfix/transport if your system uses dbm -files instead of db. +Specify dbm:/etc/postfix/transport if your system uses +dbm files instead of db. To find out what map types +Postfix supports, use the command postconf -m.

    @@ -498,7 +516,7 @@ that is connected all the time.

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             relayhost = smtprelay.someprovider.com
     
    @@ -518,7 +536,7 @@ calls from being placed, disable spontaneous SMTP mail deliveries.

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             defer_transports = smtp (Only for systems that use on-demand dialup IP)
     
    @@ -537,7 +555,7 @@ To prevent these delays, disable all SMTP client DNS lookups.

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             disable_dns_lookups = yes (Only for delivery across LANs that are disconnected most of the time)
     
    @@ -644,7 +662,7 @@ four hours, specify:

    -    /etc/postfix/main.cf
    +    /etc/postfix/main.cf:
     	delay_warning_time = 4
     
    @@ -731,6 +749,8 @@ mail for arbitrary non-local destinations:

    Don't Panic! Upgrade to a Postfix version of 19991227 or later. +To find out what Postfix version you have, execute the command +postconf mail_version.

    @@ -816,12 +836,12 @@ ahead of the other SMTPD recipient restrictions:

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             smtpd_recipient_restrictions = 
     	    regexp:/etc/postfix/regexp_access
    -	    ...other restrictions...
    +	    ...other restrictions...
     
    -    /etc/postfix/regexp_access:
    +    /etc/postfix/regexp_access:
             /[%!@].*[%!@]/ 550 Sender specified routing is not supported here.
     
    @@ -858,13 +878,13 @@ a Postfix-compatible access table with client IP address information:

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             smtpd_recipient_restrictions =
                 permit_mynetworks
                 check_client_access hash:/etc/postfix/client_access
                 check_relay_domains
     
    -    /etc/postfix/client_access:
    +    /etc/postfix/client_access:
             4.3.2.1         OK
             5.4.3.2         987654321
     
    @@ -872,7 +892,8 @@ a Postfix-compatible access table with client IP address information:

    Specify dbm instead of hash if your system uses -dbm files instead of db files. +dbm files instead of db files. To find out what map +types Postfix supports, use the command postconf -m.

    @@ -893,18 +914,18 @@ spammer ever finds out the address of your users.

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             smtpd_recipient_restrictions =
                 permit_mynetworks
                 check_client_access hash:/etc/postfix/client_access
                 check_sender_access hash:/etc/postfix/sender_access
                 check_relay_domains
     
    -    /etc/postfix/client_access:
    +    /etc/postfix/client_access:
             11.22.33                OK
             dialup.isp.com          OK
     
    -    /etc/postfix/sender_access:
    +    /etc/postfix/sender_access:
             joe@my.domain           OK
             blow@my.domain          OK
     
    @@ -955,7 +976,7 @@ LDAP or SQL.

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             smtpd_recipient_restrictions =
                 hash:/etc/postfix/restricted_senders
                 ...other stuff...
    @@ -963,11 +984,11 @@ LDAP or SQL.
             restriction_classes = local_only
             local_only = check_recipient_access hash:/etc/postfix/local_domains, reject
     
    -    /etc/postfix/restricted_senders:
    +    /etc/postfix/restricted_senders:
             foo@domain      local_only
             bar@domain      local_only
     
    -    /etc/postfix/local_domains:
    +    /etc/postfix/local_domains:
             this.domain     OK      (matches this.domain and subdomains)
             that.domain     OK      (matches that.domain and subdomains)
     
    @@ -975,7 +996,8 @@ LDAP or SQL.

    Specify dbm instead of hash if your system uses -dbm files instead of db files. +dbm files instead of db files. To find out what map +types Postfix supports, use the command postconf -m.

    @@ -1077,6 +1099,66 @@ and convince the person responsible for it to fix the configuration.


    +

    Postfix does not try all the MX +addresses

    + +When delivering mail, Postfix tries all MX addresses in order of +preference, and stops at the first server that speaks SMTP. + +

    + +If the first server that speaks SMTP rejects the connection by +greeting the client with a 5xx status code, which means "I will +never accept your mail", Postfix gives up and bounces the message +to the sender. + +

    + +If the first server that speaks SMTP rejects the connection by +greeting the client with a 4xx status code, which means "come back +later", Postfix backs off and defers delivery until later. + +

    + +Some people will argue that Postfix should contact the other MX +addresses even when the server greets with 4xx or 5xx, if only +because that is what Sendmail does, and of course we know that +everything Sendmail does is right. + +

    + +Unfortunately, some people configure their infrastructure badly. +Their most preferred MX server is visible to the world but it +rejects connections from outside with a 5xx or 4xx greeting. Just +because Sendmail goes to the second-best MX server, these people +assume that every mailer will do so. + +

    + +If such configurations are a problem for you, below are some controls +that work around them. + +

    + +

    +    /etc/postfix/main.cf:
    +	smtp_skip_4xx_greeting = yes
    +	smtp_skip_5xx_greeting = yes
    +
    + +

    + +The smtp_skip_5xx_greeting is present in Postfix releases +later than 20000104. To find out what Postfix version you have, +use the command postconf mail_version. + +

    + +Execute the command postfix reload to make the change +effective immediately. + +


    +

    Root's mail is delivered to nobody

    If you use
    procmail (or some other command) @@ -1101,7 +1183,7 @@ real user.

    -/etc/aliases:
    +/etc/aliases:
         root:       you
     
    @@ -1122,12 +1204,17 @@ To find out the location for your system, execute the command

    Postfix accepts mail for non-existing local users

    -The information in this section applies to Postfix versions 19991216 -and later. See elsewhere for
    unknown +See elsewhere for how to reject mail for unknown virtual users.

    +The information in this section applies to Postfix versions 19991216 +and later. To find out what Postfix version you have, execute the +command postconf mail_version. + +

    + By default, the Postfix SMTP server does not know what local users exist, and will happily accept mail for unknown@your.site. The reason is that different local delivery agents have different @@ -1139,27 +1226,31 @@ Of course mail for a non-existent local user will eventually bounce as undeliverable, but why accept such mail in the first place? You can tell the Postfix SMTP server how to find out if a user exists by listing all tables with local addresses in the local_recipient_maps -parameter: +parameter. + +

    + +For example, if you use the default Postfix local delivery agent +in /etc/postfix/master.cf, specify:

    -    /etc/postfix/main.cf:
    -	local_recipient_maps = $alias_maps, unix:passwd.byname
    +    /etc/postfix/main.cf:
    +	local_recipient_maps = $relocated_maps $alias_maps, unix:passwd.byname
     

    -The above should work on UNIX systems, provided that you use the -Postfix local delivery agent. However, if you run the Postfix SMTP -server chrooted, on some systems it will be necessary to have a -copy of the passwd file inside the chroot jail (typically: in -/var/spool/postfix/etc). +However, if you run the Postfix SMTP server chrooted, on some +systems it will be necessary to have a copy of the passwd file +inside the chroot jail (typically: in /var/spool/postfix/etc). +The only way to find out is to try.

    By default, the Postfix SMTP server does know about Postfix virtual maps, and will reject mail for +href="#virtual_setup">virtual maps, and will reject mail for unknown@virtual.domain without further configuration.


    @@ -1175,7 +1266,7 @@ domain is to be appended to addresses that do not have a domain:

    -/etc/postfix/main.cf:
    +/etc/postfix/main.cf:
         myorigin = domain.name
     
    @@ -1188,10 +1279,10 @@ destinations:

    -/etc/postfix/main.cf:
    +/etc/postfix/main.cf:
         virtual_maps = hash:/etc/postfix/virtual
     
    -/etc/postfix/virtual:
    +/etc/postfix/virtual:
         root        root@localhost
         postmaster  postmaster@localhost
     
    @@ -1199,7 +1290,8 @@ destinations:

    Specify dbm instead of hash if your system uses -dbm files instead of db files. +dbm files instead of db files. To find out what map +types Postfix supports, use the command postconf -m.

    @@ -1225,7 +1317,7 @@ for example:

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             home_mailbox = Maildir/
     
    @@ -1259,10 +1351,10 @@ For example:

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             mailbox_command = /path/to/procmail
     
    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             mailbox_command = /path/to/procmail -a $EXTENSION
     
    @@ -1351,29 +1443,16 @@ expression-based filter at the SMTP port:

    -

    +
    +    /etc/postfix/main.cf:
    +	smtpd_recipient_restrictions = 
    +	    ... regexp:/etc/postfix/access_regexp ...
    +	smtpd_recipient_restrictions = 
    +	    ... pcre:/etc/postfix/access_regexp ...
     
    -
    /etc/postfix/main.cf: - -
    - -
    smtpd_recipient_restrictions = ... regexp:/etc/postfix/access_regexp ... - -
    smtpd_recipient_restrictions = ... pcre:/etc/postfix/access_regexp ... - -
    - -

    - -

    /etc/postfix/access_regexp: - -
    - -
    /^(.*)-outgoing@(.*)/ 554 Use $1@$2 instead - -
    - -
    + /etc/postfix/access_regexp: + /^(.*)-outgoing@(.*)/ 554 Use $1@$2 instead +

    @@ -1418,11 +1497,10 @@ script to strip any header lines that match:

    -

    +
    +    /delivered-to/i
     
    -
    /delivered-to/i - -
    +

    @@ -1456,19 +1534,20 @@ to IP spoofing.

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             smtpd_recipient_restrictions =
                 hash:/etc/postfix/access
                 ..the usual stuff...
     
    -    /etc/postfix/access:
    +    /etc/postfix/access:
             all     permit_mynetworks,reject
     

    Specify dbm instead of hash if your system uses -dbm files instead of db files. +dbm files instead of db files. To find out what map +types Postfix supports, use the command postconf -m.

    @@ -1492,7 +1571,7 @@ therefore is subject to SMTP sender spoofing.

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             smtpd_recipient_restrictions =
                 hash:/etc/postfix/protected_destinations
                 ..the usual stuff...
    @@ -1500,11 +1579,11 @@ therefore is subject to SMTP sender spoofing.
             smtpd_restriction_classes = insiders_only
             insiders_only = check_sender_access hash:/etc/postfix/insiders, reject
     
    -    /etc/postfix/protected_destinations:
    +    /etc/postfix/protected_destinations:
             all@my.domain   insiders_only
             all@my.hostname insiders_only
     
    -    /etc/postfix/insiders:
    +    /etc/postfix/insiders:
             my.domain       OK
             another.domain  OK
     
    @@ -1527,6 +1606,67 @@ sense to make it moderated.
    +

    How to configure a Postfix virtual domain

    + +Problem: + +

    + +

    + +

    + +Solution: + +

    + +

    + +

    + +For more information on how to set up virtual domains, see the virtual manual page. + +


    +

    Commands don't work in Postfix virtual maps

    Delivering mail to a command is a security-sensitive operation, @@ -1556,7 +1696,7 @@ privileges.

    -    /etc/aliases:
    +    /etc/aliases:
             name-virtual.domain     "|/some/where/command..."
     
    @@ -1572,7 +1712,7 @@ alias database.

    -    /etc/postfix/virtual:
    +    /etc/postfix/virtual:
             virtual.domain          whatever
             name@virtual.domain     name-virtual.domain
     
    @@ -1593,67 +1733,69 @@ To find out the location for your system, execute the command
    -

    Rejecting mail for unknown virtual users

    +

    Receiving a virtual domain in a mailbox

    -Problem: mail for an unknown virtual user is misdelivered to a local -user with the same name. +Question: how to receive all mail for a domain in a mailbox without +losing the original recipient information? The Postfix Delivered-To: +mail header shows only the mailbox owner, not the virtual address +that the mail was sent to.

    -Problem: mail for an unknown virtual user results in an ugly "mail -loops back to myself" error from Postfix. +Answer: I hope we all agree that delivering a domain to a mailbox +is disgusting practice. Forwarding mail via SMTP or UUCP would be +a much better choice. Unfortunately, neither SMTP nor UUCP are a +usable alternative for legions of windows users.

    -Solution: add a magical entry to the Postfix virtual database: +That said, it is possible to propagate the original virtual recipient +information to the Delivered-To: header. The trick is to use a +virtual map that uses regular expressions instead of the more +traditional indexed files. + +

    + +The following delivers username@virtual.domain with a +Delivered-To: message header that contains joe+username@your.domain. +Postfix already puts the envelope sender address in the Return-Path: +header. The information in the Delivered-To: and Return-Path: +headers is sufficient to reliably implement a domain in a mailbox.

    -    /etc/postfix/virtual:
    -        virtual.domain whatever
    +    /etc/postfix/main.cf:
    +	recipient_delimiter = +
    +	virtual_maps = 
    +	    ...non-regexp virtual maps...
    +	    regexp:/etc/postfix/virtual_regexp
    +
    +    /etc/postfix/virtual_regexp:
    +	/^virtual\.domain$/		whatever
    +	/^(.*\)@virtual\.domain$/	joe+$1
     

    -This entry will also fix the problem that the Postfix SMTP server -refuses to receive mail for the virtual -domain. - -

    - -For more information on how to set up virtual domains, see the virtual manual page. - -


    - -

    Postfix refuses to receive mail for some -virtual domains

    - -In order to receive mail for virtual domains, the Postfix SMTP server -needs to know that the domain is OK. - -

    +Notes:

    -

    - -For more details, see the virtual -manual page. -


    Address masquerading with exceptions

    @@ -1675,7 +1817,7 @@ coming from user@my.domain, specify:

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             masquerade_domains = $mydomain
     
    @@ -1702,7 +1844,7 @@ such as root, specify:

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             masquerade_exceptions = root
     
    @@ -1714,7 +1856,7 @@ such as root, specify:

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             masquerade_domains = somehost.my.domain otherhost.my.domain $mydomain
     
    @@ -1760,7 +1902,7 @@ Examples:

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             mailbox_command = /some/program ...
     
    @@ -1768,14 +1910,14 @@ Examples: This example specifies a command that delivers all local mail to mailbox. See the sample main.cf file for examples. In -/etc/aliases, you must specify an alias for root that +/etc/aliases, you must specify an alias for root that directs mail to a real person, otherwise mail sent to root will not work as expected.

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             mailbox_transport = foo
     
    @@ -1801,7 +1943,7 @@ host.
  • You need an rmail program that extracts the sender address from mail that arrives via UUCP, and that feeds the mail -into the Postfix sendmail command. Most UNIX systems come +into the Postfix sendmail command. Most UNIX systems come with an rmail utility. If you're in a pinch, try the one bundled with the Postfix source code in the auxiliary directory. Some day Postfix may have its own rmail command. @@ -1814,7 +1956,7 @@ be delivered via UUCP, for example, to a host named uucp-host:

    -    /etc/postfix/transport:
    +    /etc/postfix/transport:
             some.domain     uucp:uucp-host
             .some.domain    uucp:uucp-host
     
    @@ -1836,21 +1978,22 @@ you change the transport file.

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             transport_maps = hash:/etc/postfix/transport
     

    Specify dbm instead of hash if your system uses -dbm files instead of db files. +dbm files instead of db files. To find out what map +types Postfix supports, use the command postconf -m.

  • Define a mail transport for delivery via UUCP:
    -    /etc/postfix/master.cf:
    +    /etc/postfix/master.cf:
             uucp      unix  -       n       n       -       -       pipe
               flags=F user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
     
    @@ -1870,7 +2013,7 @@ is willing to relay mail for.

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             relay_domains = some.domain $mydestination ...
     
    @@ -1908,7 +2051,7 @@ mail transport to your UUCP gateway host, say, uucp-gateway:

    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             relayhost = uucp-gateway
             default_transport = uucp
     
    @@ -1920,7 +2063,7 @@ mail transport to your UUCP gateway host, say, uucp-gateway:

    -    /etc/postfix/master.cf:
    +    /etc/postfix/master.cf:
             uucp      unix  -       n       n       -       -       pipe
               flags=F user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
     
    @@ -1953,21 +2096,22 @@ HylaFax. Here's the setup used:

    -    /etc/postfix/master.cf:
    +    /etc/postfix/master.cf:
             fax       unix  -       n       n       -       -       pipe
                 flags= user=fax argv=/usr/bin/faxmail -d -n ${user}
     
    -    /etc/postfix/transport:
    +    /etc/postfix/transport:
             fax.your.domain   fax:localhost
     
    -    /etc/postfix/main.cf:
    +    /etc/postfix/main.cf:
             transport_maps = hash:/etc/postfix/transport
     

    Specify dbm instead of hash if your system uses -dbm files instead of db files. +dbm files instead of db files. To find out what map +types Postfix supports, use the command postconf -m.

    @@ -2031,7 +2175,7 @@ Fix: get rid of the third-party ndbm.h include file.


    -

    Using DB libraries on Solaris etc.

    +

    Using third-party DB libraries

    The old dbm UNIX database has severe limitations when you try to store lots of information. It breaks when the number of hash @@ -2049,9 +2193,10 @@ version which has a db-1.85 compatible interface.

    -Use the following commands in the Postfix top-level directory. -The LD_LIBRARY_PATH unset commands may be required to avoid linking -in the wrong libraries. +To build with a third-party DB library, use the following commands +in the Postfix top-level directory. +On Solaris, the LD_LIBRARY_PATH unset commands may be required to +avoid linking in the wrong libraries.

    diff --git a/postfix/makedefs b/postfix/makedefs index 505186909..1627dcb0b 100644 --- a/postfix/makedefs +++ b/postfix/makedefs @@ -51,6 +51,11 @@ ARFL=rv SYSTEM=`(uname -s) 2>/dev/null` RELEASE=`(uname -r) 2>/dev/null` +VERSION=`(uname -v) 2>/dev/null` + +case "$VERSION" in + dcosx*) SYSTEM=$VERSION;; +esac case "$SYSTEM.$RELEASE" in UnixWare.5*) SYSTYPE=UW7 @@ -195,6 +200,11 @@ ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543 : ${CC=cc} AWK=gawk ;; + dcosx.1*) SYSTYPE=DCOSX1 + RANLIB=echo + SYSLIBS="-lresolv -lsocket -lnsl -lc -lrpcsvc -L/usr/ucblib -lucb" + ;; + ".") if [ -d /NextApps ]; then SYSTYPE=`hostinfo | sed -n \ 's/^.*NeXT Mach 3.*$/NEXTSTEP3/;/NEXTSTEP3/{p;q;}'` diff --git a/postfix/master/master_status.c b/postfix/master/master_status.c index 4cc54db2f..40ad1508a 100644 --- a/postfix/master/master_status.c +++ b/postfix/master/master_status.c @@ -41,7 +41,6 @@ /* System libraries. */ #include -#include #include /* Utility library. */ @@ -155,10 +154,10 @@ void master_status_init(MASTER_SERV *serv) /* * Make the read end of this service's status pipe non-blocking so that - * we can detect partial writes on the child side. We use a socket pair, + * we can detect partial writes on the child side. We use a duplex pipe * so that the child side becomes readable when the master goes away. */ - if (socketpair(AF_UNIX, SOCK_STREAM, 0, serv->status_fd) < 0) + if (duplex_pipe(serv->status_fd) < 0) msg_fatal("pipe: %m"); non_blocking(serv->status_fd[0], BLOCKING); close_on_exec(serv->status_fd[0], CLOSE_ON_EXEC); diff --git a/postfix/smtp/smtp.c b/postfix/smtp/smtp.c index 1e6c46a51..a6c8f0f21 100644 --- a/postfix/smtp/smtp.c +++ b/postfix/smtp/smtp.c @@ -87,6 +87,8 @@ /* postmaster with transcripts of SMTP sessions with protocol errors. /* .IP \fBsmtp_skip_4xx_greeting\fR /* Skip servers that greet us with a 4xx status code. +/* .IP \fBsmtp_skip_5xx_greeting\fR +/* Skip servers that greet us with a 5xx status code. /* .IP \fBsmtp_skip_quit_response\fR /* Do not wait for the server response after sending QUIT. /* .SH "Resource controls" @@ -199,6 +201,7 @@ char *var_debug_peer_list; int var_debug_peer_level; char *var_notify_classes; int var_smtp_skip_4xx_greeting; +int var_smtp_skip_5xx_greeting; int var_ign_mx_lookup_err; int var_skip_quit_resp; char *var_fallback_relay; @@ -350,6 +353,7 @@ int main(int argc, char **argv) }; static CONFIG_BOOL_TABLE bool_table[] = { VAR_SMTP_SKIP_4XX, DEF_SMTP_SKIP_4XX, &var_smtp_skip_4xx_greeting, + VAR_SMTP_SKIP_5XX, DEF_SMTP_SKIP_5XX, &var_smtp_skip_5xx_greeting, VAR_IGN_MX_LOOKUP_ERR, DEF_IGN_MX_LOOKUP_ERR, &var_ign_mx_lookup_err, VAR_SKIP_QUIT_RESP, DEF_SKIP_QUIT_RESP, &var_skip_quit_resp, 0, diff --git a/postfix/smtp/smtp_connect.c b/postfix/smtp/smtp_connect.c index 50ce89135..0a9ad31fe 100644 --- a/postfix/smtp/smtp_connect.c +++ b/postfix/smtp/smtp_connect.c @@ -227,6 +227,17 @@ static SMTP_SESSION *smtp_connect_addr(DNS_RR *addr, unsigned port, vstream_fclose(stream); return (0); } + + /* + * Skip this host if it sends a 5xx greeting. + */ + if (ch == '5' && var_smtp_skip_5xx_greeting) { + vstring_sprintf(why, "connect to %s[%s]: server refused mail service", + addr->name, inet_ntoa(sin.sin_addr)); + smtp_errno = SMTP_RETRY; + vstream_fclose(stream); + return (0); + } vstream_ungetc(stream, ch); return (smtp_session_alloc(stream, addr->name, inet_ntoa(sin.sin_addr))); } diff --git a/postfix/smtpd/smtpd_check.c b/postfix/smtpd/smtpd_check.c index 0171c1e6a..2c5101997 100644 --- a/postfix/smtpd/smtpd_check.c +++ b/postfix/smtpd/smtpd_check.c @@ -811,6 +811,7 @@ static int permit_auth_destination(char *recipient) */ canon_addr_internal(query, recipient); resolve_clnt_query(STR(query), &reply); + lowercase(STR(reply.recipient)); /* * Handle special case that is not supposed to happen. @@ -947,6 +948,7 @@ static int permit_mx_backup(SMTPD_STATE *unused_state, const char *recipient) */ canon_addr_internal(query, recipient); resolve_clnt_query(STR(query), &reply); + lowercase(STR(reply.recipient)); /* * If the destination is local, it is acceptable, because we are @@ -1088,6 +1090,7 @@ static int reject_unknown_address(SMTPD_STATE *state, char *addr, */ canon_addr_internal(query, addr); resolve_clnt_query(STR(query), &reply); + lowercase(STR(reply.recipient)); /* * Skip local destinations and non-DNS forms. @@ -1369,6 +1372,7 @@ static int check_mail_access(SMTPD_STATE *state, char *table, char *addr, */ canon_addr_internal(query, addr); resolve_clnt_query(STR(query), &reply); + lowercase(STR(reply.recipient)); /* * Garbage in, garbage out. Every address from canon_addr_internal() and @@ -1929,6 +1933,7 @@ char *smtpd_check_rcptmap(SMTPD_STATE *state, char *recipient) */ canon_addr_internal(query, recipient); resolve_clnt_query(STR(query), &reply); + lowercase(STR(reply.recipient)); /* * Skip non-DNS forms. Skip non-local numerical forms. @@ -1949,6 +1954,18 @@ char *smtpd_check_rcptmap(SMTPD_STATE *state, char *recipient) #define NOP ((char **) 0) if (resolve_local(domain)) { + if (*var_virtual_maps + && maps_find(virtual_maps, domain, 0)) { + msg_warn("virtual domain \"%s\" is listed in $mydestination", + domain); + msg_warn("the $local_recipient_maps feature requires that no"); + msg_warn("virtual domains are listed in $mydestination"); + msg_warn("be sure to specify the required \"%s whatever\"", + domain); + msg_warn("entry in the virtual map, as explained in the man"); + msg_warn("page and in the FAQ entry for virtual domains"); + SMTPD_CHECK_RCPT_RETURN(0); + } if (*var_local_rcpt_maps && !mail_addr_find(rcpt_canon_maps, STR(reply.recipient), NOP) && !mail_addr_find(canonical_maps, STR(reply.recipient), NOP) diff --git a/postfix/util/Makefile.in b/postfix/util/Makefile.in index b13d41aa2..7fe7b2e5b 100644 --- a/postfix/util/Makefile.in +++ b/postfix/util/Makefile.in @@ -20,7 +20,7 @@ SRCS = argv.c argv_split.c attr.c basename.c binhash.c chroot_uid.c \ vstream.c vstream_popen.c vstring.c vstring_vstream.c writable.c \ write_buf.c write_wait.c dict_unix.c dict_pcre.c stream_listen.c \ stream_connect.c stream_trigger.c dict_regexp.c mac_expand.c \ - clean_env.c watchdog.c spawn_command.c + clean_env.c watchdog.c spawn_command.c duplex_pipe.c OBJS = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \ close_on_exec.o concatenate.o dict.o dict_db.o dict_dbm.o \ dict_env.o dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \ @@ -42,7 +42,7 @@ OBJS = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \ vstream.o vstream_popen.o vstring.o vstring_vstream.o writable.o \ write_buf.o write_wait.o dict_unix.o dict_pcre.o stream_listen.o \ stream_connect.o stream_trigger.o dict_regexp.o mac_expand.o \ - clean_env.o watchdog.o spawn_command.o + clean_env.o watchdog.o spawn_command.o duplex_pipe.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 \ @@ -439,6 +439,9 @@ doze.o: doze.c doze.o: sys_defs.h doze.o: msg.h doze.o: iostuff.h +duplex_pipe.o: duplex_pipe.c +duplex_pipe.o: sys_defs.h +duplex_pipe.o: iostuff.h environ.o: environ.c environ.o: sys_defs.h events.o: events.c @@ -863,6 +866,7 @@ vstream_popen.o: vbuf.h vstream_popen.o: argv.h vstream_popen.o: set_ugid.h vstream_popen.o: clean_env.h +vstream_popen.o: iostuff.h vstring.o: vstring.c vstring.o: sys_defs.h vstring.o: mymalloc.h diff --git a/postfix/util/duplex_pipe.c b/postfix/util/duplex_pipe.c new file mode 100644 index 000000000..33d833993 --- /dev/null +++ b/postfix/util/duplex_pipe.c @@ -0,0 +1,47 @@ +/*++ +/* NAME +/* duplex_pipe 3 +/* SUMMARY +/* local IPD +/* SYNOPSIS +/* #include +/* +/* int duplex_pipe(fds) +/* int *fds; +/* DESCRIPTION +/* duplex_pipe() uses whatever local primitive it takes +/* to get a two-way I/O channel. +/* DIAGNOSTICS +/* A null result means success. In case of error, the result +/* is -1 and errno is set to the appropriate number. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +/* System libraries */ + +#include +#include + +/* Utility library. */ + +#include "iostuff.h" + +/* duplex_pipe - give me a duplex pipe or bust */ + +int duplex_pipe(int *fds) +{ +#ifdef HAS_DUPLEX_PIPE + return (pipe(fds)); +#else + return (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)); +#endif +} + diff --git a/postfix/util/iostuff.h b/postfix/util/iostuff.h index 909bffb5e..32d350006 100644 --- a/postfix/util/iostuff.h +++ b/postfix/util/iostuff.h @@ -25,6 +25,7 @@ extern int read_wait(int, int); extern int write_wait(int, int); extern int write_buf(int, const char *, int, int); extern void doze(unsigned); +extern int duplex_pipe(int *); #define BLOCKING 0 #define NON_BLOCKING 1 diff --git a/postfix/util/safe_open.c b/postfix/util/safe_open.c index c5a1aa591..fae3e5341 100644 --- a/postfix/util/safe_open.c +++ b/postfix/util/safe_open.c @@ -45,6 +45,14 @@ /* A safe open routine was discussed by Casper Dik in article /* <2rdb0s$568@mail.fwi.uva.nl>, posted to comp.security.unix /* (May 18, 1994). +/* +/* Olaf Kirch discusses how the lstat()/open()+stat() test can +/* be fooled by delaying the open() until the inode found with +/* lstat() has been re-used for a sensitive file (article +/* <20000103212443.A5807@monad.swb.de> posted to bugtraq on +/* Jan 3, 2000). This can be a concern for set-uid processes +/* that run under the control of a user and this can be +/* manipulated with start/stop signals. /* LICENSE /* .ad /* .fi @@ -107,11 +115,17 @@ static VSTREAM *safe_open_exist(const char *path, int flags, VSTRING *why) * either we followed a symlink while opening an existing file, someone * quickly changed the number of hard links, or someone replaced the file * after the open() call. The link and mode tests aren't really necessary - * but the additional cost is low. + * in daemon processes. Set-uid programs, on the other hand, can be + * slowed down by arbitrary amounts, and there it would make sense to + * compare even more file attributes, such as the inode generation number + * on systems that have one. */ else if (lstat(path, &lstat_st) < 0 || fstat_st.st_dev != lstat_st.st_dev || fstat_st.st_ino != lstat_st.st_ino +#ifdef HAS_ST_GEN + || fstat_st.st_gen != lstat_st.st_gen +#endif || fstat_st.st_nlink != lstat_st.st_nlink || fstat_st.st_mode != lstat_st.st_mode) { vstring_sprintf(why, "file %s: status has changed", path); diff --git a/postfix/util/sys_defs.h b/postfix/util/sys_defs.h index 0cfa3fde2..9ad93b870 100644 --- a/postfix/util/sys_defs.h +++ b/postfix/util/sys_defs.h @@ -21,7 +21,7 @@ */ #if defined(FREEBSD2) || defined(FREEBSD3) || defined(FREEBSD4) \ || defined(BSDI2) || defined(BSDI3) || defined(BSDI4) \ - || defined(OPENBSD2) || defined(NETBSD1) || defined(RHAPSODY5) + || defined(OPENBSD2) || defined(NETBSD1) #define SUPPORTED #include #define USE_PATHS_H @@ -37,9 +37,14 @@ #define USE_STATFS #define STATFS_IN_SYS_MOUNT_H #define HAS_POSIX_REGEXP +#define HAS_ST_GEN /* struct stat contains inode generation number */ #endif -#if defined(OPENBSD2) +#if defined(FREEBSD2) || defined(FREEBSD3) || defined(FREEBSD4) +#define HAS_DUPLEX_PIPE +#endif + +#if defined(OPENBSD2) || defined(FREEBSD3) || defined(FREEBSD4) #define HAS_ISSETUGID #endif @@ -48,6 +53,21 @@ #endif #if defined(RHAPSODY5) +#define SUPPORTED +#include +#define USE_PATHS_H +#define USE_FLOCK_LOCK +#define HAS_SUN_LEN +#define HAS_FSYNC +#define HAS_DB +#define HAS_SA_LEN +#define DEF_DB_TYPE "hash" +#define ALIAS_DB_MAP "hash:/etc/aliases" +#define GETTIMEOFDAY(t) gettimeofday(t,(struct timezone *) 0) +#define ROOT_PATH "/bin:/usr/bin:/sbin:/usr/sbin" +#define USE_STATFS +#define STATFS_IN_SYS_MOUNT_H +#define HAS_POSIX_REGEXP #define NORETURN void #define HAS_NETINFO #endif @@ -62,8 +82,8 @@ #define UNSAFE_CTYPE /* XXX verify */ #define _PATH_MAILDIR "/var/spool/mail" #define _PATH_BSHELL "/bin/sh" -#define _PATH_DEFPATH "/usr/bin:/usr/ucb" -#define _PATH_STDPATH "/usr/bin:/usr/etc:/usr/ucb" +#define _PATH_DEFPATH "/bin:/usr/bin:/usr/ucb" +#define _PATH_STDPATH "/bin:/usr/bin:/usr/etc:/usr/ucb" #define USE_FLOCK_LOCK #define USE_DOT_LOCK #define HAS_FSYNC @@ -79,6 +99,7 @@ extern int optind; extern char *optarg; extern int opterr; +extern int h_errno; #define MISSING_STRFTIME_E #define HAS_NIS @@ -554,6 +575,34 @@ extern int opterr; /* XXX use */ #define USE_STATVFS #define STATVFS_IN_SYS_STATVFS_H #define MISSING_USLEEP +#endif + +#ifdef DCOSX1 /* Siemens Pyramid */ +#define SUPPORTED +#include +#define _PATH_MAILDIR "/var/mail" +#define _PATH_BSHELL "/bin/sh" +#define _PATH_DEFPATH "/usr/bin:/usr/ucb" +#define _PATH_STDPATH "/usr/bin:/usr/sbin:/usr/ucb" +#define MISSING_SETENV +#define USE_FCNTL_LOCK +#define USE_DOT_LOCK +#define HAS_FSYNC +#define DEF_DB_TYPE "hash" +#define ALIAS_DB_MAP "hash:/etc/aliases" +/* Uncomment the following line if you have NIS package installed */ +/* #define HAS_NIS */ +#define USE_SYS_SOCKIO_H +#define GETTIMEOFDAY(t) gettimeofday(t,NULL) +#define ROOT_PATH "/bin:/usr/bin:/sbin:/usr/sbin:/usr/ucb" +#define FIONREAD_IN_SYS_FILIO_H +#define DBM_NO_TRAILING_NULL +#define USE_STATVFS +#define STATVFS_IN_SYS_STATVFS_H +#define UNIX_DOMAIN_CONNECT_BLOCKS_FOR_ACCEPT +#ifndef S_ISSOCK +#define S_ISSOCK(mode) ((mode&0xF000) == 0xC000) +#endif #endif /* @@ -721,7 +770,7 @@ typedef int pid_t; /* * Making the ctype.h macros not more expensive than necessary. On some - * systems, ctype.h misbehaves badly with signed characters. + * systems, ctype.h misbehaves with non-ASCII and/or negative characters. */ #define _UCHAR_(c) ((unsigned char)(c)) #ifdef UNSAFE_CTYPE diff --git a/postfix/util/vstream_popen.c b/postfix/util/vstream_popen.c index 4e741603c..82a7a0c90 100644 --- a/postfix/util/vstream_popen.c +++ b/postfix/util/vstream_popen.c @@ -20,7 +20,7 @@ /* \fIcommand\fR, which is executed by a child process. The \fIflags\fR /* argument is as with vstream_fopen(). The child's standard input and /* standard output are redirected to the stream, which is based on a -/* socketpair. +/* socketpair or other suitable local IPC. /* /* vstream_popen_vargs() offers the user more control over the /* child process and over how it is managed. The key argument @@ -90,7 +90,6 @@ /* System library. */ #include -#include #include #include #include @@ -108,6 +107,7 @@ #include #include #include +#include /* Application-specific. */ @@ -207,7 +207,7 @@ VSTREAM *vstream_popen_vargs(int flags,...) if (args.command == 0) args.command = args.argv[0]; - if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) < 0) + if (duplex_pipe(sockfd) < 0) return (0); switch (pid = fork()) {