From: Wietse Venema Date: Sat, 14 Apr 2001 05:00:00 +0000 (-0500) Subject: snapshot-20010414 X-Git-Tag: v1.1.0~67 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a48e59c06470fa2390fb3b8e10d63cb148aa3729;p=thirdparty%2Fpostfix.git snapshot-20010414 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index a3a8eb3ae..b9fd3d3e9 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -5031,3 +5031,49 @@ Apologies for any names omitted. before the server has received the client's data. Files: util/{inet,unix,stream}_trigger.c, util/events.c, master/master_trigger.c, postkick/postkick.c. + +20010403 + + Workaround: the mysql library can return null pointers + rather than zero-length strings. + +20010404 + + Logging: log additional information about why "mail for + XXX loops back to myself", when the local machine is the + best MX host. File: smtp/smtp_addr.c. + +20010406 + + Changed some noisy LDAP client warnings into optional + logging. LaMont Jones, util/dict_ldap.c. + +20010411 + + Compatibility: the SMTP server now replies with 550 instead + of 503 when it receives the DATA command without having + received a valid recipient address. This is needed for the + Sendmail client-side pipelining implementation. Problem + reported by Lutz Jaenicke. File: smtpd/smtpd.c. + + Cleanup: shut up if chattr fails on Reiserfs and other file + systems that do not support the respective attributes. + Files: conf/postfix-script-{no,}sgid. + +20010413 + + Ergonomics: Postfix applications now warn when a DB or DBM + file is out of date, and recommends to re-run postmap or + postalias. Files: util/dict_db.c, util/dict_dbm.c. + +20010414 + + Feature: specify a key of "-" to the postmap or postalias + -q or -d option, and the keys will be read from standard + input, one key per line. Files: postmap/postmap.c, + postalias/postalias.c. + + Bugfix: with a non-default inet_interfaces setting, the + master daemon ignored host information in explicit host:port + settings in master.cf. Fix by Jun-ichiro itojun Hagino @ + iijlab.net. Files: master/master.h, master/master_ent.c. diff --git a/postfix/INSTALL b/postfix/INSTALL index 427a4528c..f75095ad6 100644 --- a/postfix/INSTALL +++ b/postfix/INSTALL @@ -67,9 +67,9 @@ If your system is supported, it is one of Linux RedHat 5.x Linux RedHat 6.x Linux RedHat 7.x - Linux Slackware 3.5 - Linux Slackware 4.0 - Linux Slackware 7.0 + Linux Slackware 3.x + Linux Slackware 4.x + Linux Slackware 7.x Linux SuSE 5.x Linux SuSE 6.x Linux SuSE 7.x diff --git a/postfix/SASL_README b/postfix/SASL_README index 801d4f9af..a976da9c8 100644 --- a/postfix/SASL_README +++ b/postfix/SASL_README @@ -62,14 +62,8 @@ Reportedly, Microsoft Internet Explorer version 5 requires the non-standard SASL LOGIN authentication method. To enable this authentication method, specify ``./configure --enable-login''. -Older Microsoft SMTP client software implements a non-standard -version of the AUTH protocol syntax, and expects that the SMTP -server replies to EHLO with "250 AUTH=stuff" instead of "250 AUTH -stuff". To accomodate such clients in addition to conformant -clients, set "broken_sasl_auth_clients = yes" in the main.cf file. - -The Postfix SMTP client is backwards compatible with SMTP servers -that use the non-standard AUTH protocol syntax. +If you install the Cyrus SASL libraries as per the default, you +will have to symlink /usr/lib/sasl -> /usr/local/lib/sasl. Building Postfix with SASL authentication support ================================================= @@ -94,9 +88,6 @@ otherwise ld.so will not find the SASL shared library: Enabling SASL authentication in the Postfix SMTP server ======================================================= -If you installed the Cyrus SASL libraries as per the default, you -will have to symlink /usr/lib/sasl -> /usr/local/lib/sasl. - See conf/sample-auth.cf for examples. In order to enable SASL support in the SMTP server: @@ -141,6 +132,12 @@ EXAMPLE: saslpasswd -c -u `postconf -h myhostname` exampleuser To run software chrooted with SASL support is an interesting exercise. It probably is not worth the trouble. +Older Microsoft SMTP client software implements a non-standard +version of the AUTH protocol syntax, and expects that the SMTP +server replies to EHLO with "250 AUTH=stuff" instead of "250 AUTH +stuff". To accomodate such clients in addition to conformant +clients, set "broken_sasl_auth_clients = yes" in the main.cf file. + Testing SASL authentication in the Postfix SMTP server ====================================================== @@ -192,3 +189,8 @@ remote part of an email address). The SASL client password file is opened before the SMTP server enters the optional chroot jail, so you can keep the file in /etc/postfix. + +The Postfix SMTP client is backwards compatible with SMTP servers +that use the non-standard AUTH=stuff... syntax in response to the +EHLO command. + diff --git a/postfix/conf/postfix-script-nosgid b/postfix/conf/postfix-script-nosgid index d102a0e3b..f84536675 100755 --- a/postfix/conf/postfix-script-nosgid +++ b/postfix/conf/postfix-script-nosgid @@ -193,7 +193,7 @@ check) test -d $dir || { $WARN creating missing Postfix $dir directory mkdir $dir || exit 1 - chmod 700 $dir; $CHATTR $dir + chmod 700 $dir; $CHATTR $dir 2>/dev/null chown $mail_owner $dir } done diff --git a/postfix/conf/postfix-script-sgid b/postfix/conf/postfix-script-sgid index d436e4df3..53bcf6303 100755 --- a/postfix/conf/postfix-script-sgid +++ b/postfix/conf/postfix-script-sgid @@ -194,7 +194,7 @@ check) test -d $dir || { $WARN creating missing Postfix $dir directory mkdir $dir || exit 1 - chmod 700 $dir; $CHATTR $dir + chmod 700 $dir; $CHATTR $dir 2>/dev/null chown $mail_owner $dir } done diff --git a/postfix/conf/sample-local.cf b/postfix/conf/sample-local.cf index f8ac3329a..285ac2448 100644 --- a/postfix/conf/sample-local.cf +++ b/postfix/conf/sample-local.cf @@ -219,12 +219,13 @@ local_destination_recipient_limit = 1 # DELIVERED-TO # -# The prepend_delivered_header controls when Postfix should prepend -# a Delivered-To: message header. +# The prepend_delivered_header controls when the Postfix local delivery +# agent should prepend a Delivered-To: message header. # -# By default, Postfix prepends a Delivered-To: header when forwarding -# mail and when delivering to file (mailbox) and command. Turning off -# the Delivered-To: header when forwarding mail is not recommended. +# By default, the Postfix local delivery agent prepends a Delivered-To: +# header when forwarding mail and when delivering to file (mailbox) +# and command. Turning off the Delivered-To: header when forwarding +# mail is not recommended. # # prepend_delivered_header = command, file, forward # prepend_delivered_header = forward diff --git a/postfix/conf/sample-misc.cf b/postfix/conf/sample-misc.cf index 9f395f898..6de986725 100644 --- a/postfix/conf/sample-misc.cf +++ b/postfix/conf/sample-misc.cf @@ -99,7 +99,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 +import_environment = MAIL_CONFIG MAIL_DEBUG MAIL_LOGTAG TZ XAUTHORITY DISPLAY # The inet_interfaces parameter specifies the network interface # addresses that this mail system receives mail on. By default, diff --git a/postfix/html/basic.html b/postfix/html/basic.html index 3333296b7..7e38a8d6c 100644 --- a/postfix/html/basic.html +++ b/postfix/html/basic.html @@ -19,7 +19,7 @@ href="rewrite.html"> Address Manipulation

Introduction

-Postfix has about 100 configuration parameters that are controlled +Postfix has several hundred configuration parameters that are controlled via the main.cf file. Fortunately, they have sensible default values. In most cases, you need to configure only two or three parameters before you can use the Postfix mail system: @@ -39,11 +39,11 @@ three parameters before you can use the Postfix mail system: The default values for many other configuration parameters are -derived from just these two. +derived from just these.

-The third parameter of interest controls the amount of mail sent +The next parameter of interest controls the amount of mail sent to the local postmaster:

Mail relaying

@@ -249,7 +254,7 @@ distribution list
  • Postfix ignores the owner-list alias -
  • Commands and mailing lists don't work in Postfix virtual maps +
  • Commands, mailing lists, and /file/name destinations don't work in Postfix virtual maps @@ -266,7 +271,7 @@ virtual domains fails with "mail loops back to myself"
  • Postfix refuses mail for virtual domains with "relay access denied" -
  • Commands and mailing lists don't work in Postfix virtual maps +
  • Commands, mailing lists, and /file/name destinations don't work in Postfix virtual maps
  • Receiving a virtual domain in a mailbox @@ -1257,6 +1262,43 @@ directory of the Postfix source code distribution.
    +

    warning: xxx.xxx.xxx.xxx: address not listed +for hostname yyy.yyy.yyy

    + +Postfix uses hostnames in its junk mail and mail relay controls. +This means that in theory someone could be motivated to set up +bogus DNS information, in order to get past your junk mail or mail +relay controls. + +

    + +When Postfix looks up the SMTP client hostname for the SMTP client +IP address, then Postfix also checks if the SMTP client IP address +is listed under the SMTP client hostname. + +

    + +If the SMTP client IP address is not listed under the SMTP client +hostname, then Postfix concludes that the SMTP client hostname does +not belong to the SMTP client IP address, and ignores the SMTP +client hostname. A warning is logged, so that you can find out why +an SMTP client is or is not stopped by your junk mail or mail relay +checks. + +

    + +You could contact the people who maintain the SMTP client's DNS +records, and explain to them that each IP address needs one PTR +record, and that this one PTR record needs a matching A record. + +

    + +Some people read the RFCs such that one IP address can have multiple +PTR records, but that makes PTR records even less useful than they +already are. And in any case, having multiple names per IP address +would only worsen the problem of finding out the "official name" +of a machine's IP address. +

    Help! Postfix is an open relay

    According to some relay checking software, Postfix accepts @@ -2416,12 +2458,12 @@ virtual manual page.
    -

    Commands and mailing lists don't work +

    Commands, mailing, and /file/name destinations don't work in Postfix virtual maps

    Short reply: specify a Sendmail-style
    virtual -domain, and specify the command or mailing list in the local aliases file. +domain, and specify the command, mailing list, or /file/name +destination in the local aliases file.

    @@ -2429,17 +2471,18 @@ Long reply follows.

    -Delivering mail to a command is a security-sensitive operation, -because the command must be executed with the right privileges. -Only root-privileged software such as the Postfix local -delivery agent can set the privileges for a command. +Delivering mail to a file or command is a security-sensitive +operation, because the operation must be executed with the right +privileges. Only root-privileged software such as the +Postfix local delivery agent can set the privileges for command +or file delivery.

    For security reasons, Postfix tries to avoid using root privileges where possible. In particular, Postfix virtual mapping is done by an unprivileged daemon, so there is no secure way to -execute commands found in virtual maps. +execute commands or to deliver to files found in virtual maps.


    diff --git a/postfix/html/pcre_table.5.html b/postfix/html/pcre_table.5.html index d27e0bb44..b04bc607b 100644 --- a/postfix/html/pcre_table.5.html +++ b/postfix/html/pcre_table.5.html @@ -47,13 +47,13 @@ PCRE_TABLE(5) PCRE_TABLE(5) is `U', which makes matching ungreedy (see PCRE documenta- tion and source for more info). - Each pattern is 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. Thus, no parent domain or parent - network search is done, and user@domain mail addresses are - not broken up into their user and domain constituent - parts, nor is user+foo broken up into user and foo. + Each pattern is applied to the entire lookup key string. + Depending on the application, that string is an entire + client hostname, an entire client IP address, or an entire + mail address. Thus, no parent domain or parent network + search is done, and user@domain mail addresses are not + broken up into their user and domain constituent parts, + nor is user+foo broken up into user and foo. Patterns are applied in the order as specified in the table, until a pattern is found that matches the search @@ -71,11 +71,11 @@ PCRE_TABLE(5) PCRE_TABLE(5) PCRE_TABLE(5) PCRE_TABLE(5) - Substitution of sub-strings from the matched expression is - possible using the conventional perl syntax ($1, $2, - etc.). The macros in the replacement string may need to be - written as ${n} or $(n) if they aren't followed by whites- - pace. + Substitution of substrings from the matched expression + into the result string is possible using the conventional + perl syntax ($1, $2, etc.). The macros in the result + string may need to be written as ${n} or $(n) if they + aren't followed by whitespace. EXAMPLES # Protect your outgoing majordomo exploders diff --git a/postfix/html/postalias.1.html b/postfix/html/postalias.1.html index 4d6e097bb..329e173f6 100644 --- a/postfix/html/postalias.1.html +++ b/postfix/html/postalias.1.html @@ -37,28 +37,28 @@ POSTALIAS(1) POSTALIAS(1) directory. -d key Search the specified maps for key and remove one - entry per map. The exit status is non-zero if the - requested information was not found. + entry per map. The exit status is zero when the + requested information was found. - -i Incremental mode. Read entries from standard input + If a key value of - is specified, the program reads + key values from the standard input stream. The exit + status is zero when at least one of the requested + keys was found. + + -i Incremental mode. Read entries from standard input and do not truncate an existing database. By - default, postalias creates a new database from the + default, postalias creates a new database from the entries in file_name. - -n Don't include the terminating null character that - terminates lookup keys and values. By default, - Postfix does whatever is the default for the host + -n Don't include the terminating null character that + terminates lookup keys and values. By default, + Postfix does whatever is the default for the host operating system. - -q key Search the specified maps for key and print the - first value found on the standard output stream. - The exit status is non-zero if the requested infor- - mation was not found. - - -r When updating a table, do not warn about duplicate - entries; silently replace them. - - -v Enable verbose logging for debugging purposes. + -q key Search the specified maps for key and print the + first value found on the standard output stream. + The exit status is zero when the requested informa- + tion was found. @@ -71,10 +71,20 @@ POSTALIAS(1) POSTALIAS(1) POSTALIAS(1) POSTALIAS(1) - Multiple -v options make the software increasingly + If a key value of - is specified, the program reads + key values from the standard input stream and + prints one line of key: value output for each key + that was found. The exit status is zero when at + least one of the requested keys was found. + + -r When updating a table, do not warn about duplicate + entries; silently replace them. + + -v Enable verbose logging for debugging purposes. Mul- + tiple -v options make the software increasingly verbose. - -w When updating a table, do not warn about duplicate + -w When updating a table, do not warn about duplicate entries; silently ignore them. Arguments: @@ -82,68 +92,67 @@ POSTALIAS(1) POSTALIAS(1) file_type The type of database to be produced. - btree The output is a btree file, named - file_name.db. This is available only on + btree The output is a btree file, named + file_name.db. This is available only on systems with support for db databases. - dbm The output consists of two files, named - file_name.pag and file_name.dir. This is - available only on systems with support for + dbm The output consists of two files, named + file_name.pag and file_name.dir. This is + available only on systems with support for dbm databases. - hash The output is a hashed file, named - file_name.db. This is available only on + hash The output is a hashed file, named + file_name.db. This is available only on systems with support for db databases. - When no file_type is specified, the software uses - the database type specified via the database_type - configuration parameter. The default value for + When no file_type is specified, the software uses + the database type specified via the database_type + configuration parameter. The default value for this parameter depends on the host environment. file_name - The name of the alias database source file when + The name of the alias database source file when rebuilding a database. DIAGNOSTICS - Problems are logged to the standard error stream. No out- + Problems are logged to the standard error stream. No out- put means no problems were detected. Duplicate entries are skipped and are flagged with a warning. postalias terminates with zero exit status in case of suc- - cess (including successful postmap -q lookup) and termi- + cess (including successful postmap -q lookup) and termi- nates with non-zero exit status in case of failure. BUGS - The "delete key" support is limited to one delete opera- - tion per command invocation. + The "delete key" support is limited to one delete -ENVIRONMENT - MAIL_CONFIG - Directory with Postfix configuration files. - MAIL_VERBOSE - Enable verbose logging for debugging purposes. + 2 - 2 - +POSTALIAS(1) POSTALIAS(1) + operation per command invocation. -POSTALIAS(1) POSTALIAS(1) +ENVIRONMENT + MAIL_CONFIG + Directory with Postfix configuration files. + MAIL_VERBOSE + Enable verbose logging for debugging purposes. CONFIGURATION PARAMETERS - The following main.cf parameters are especially relevant - to this program. See the Postfix main.cf file for syntax + The following main.cf parameters are especially relevant + to this program. See the Postfix main.cf file for syntax details and for default values. database_type - Default alias database type. On many UNIX systems, + Default alias database type. On many UNIX systems, the default type is either dbm or hash. STANDARDS @@ -154,7 +163,7 @@ POSTALIAS(1) POSTALIAS(1) sendmail(1) mail posting and compatibility interface. LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) @@ -175,15 +184,6 @@ POSTALIAS(1) POSTALIAS(1) - - - - - - - - - diff --git a/postfix/html/postmap.1.html b/postfix/html/postmap.1.html index 77833681c..5b541d105 100644 --- a/postfix/html/postmap.1.html +++ b/postfix/html/postmap.1.html @@ -56,8 +56,8 @@ POSTMAP(1) POSTMAP(1) directory. -d key Search the specified maps for key and remove one - entry per map. The exit status is non-zero if the - requested information was not found. + entry per map. The exit status is zero when the + requested information was found. @@ -71,29 +71,40 @@ POSTMAP(1) POSTMAP(1) POSTMAP(1) POSTMAP(1) - -i Incremental mode. Read entries from standard input + If a key value of - is specified, the program reads + key values from the standard input stream. The exit + status is zero when at least one of the requested + keys was found. + + -i Incremental mode. Read entries from standard input and do not truncate an existing database. By - default, postmap creates a new database from the + default, postmap creates a new database from the entries in file_name. - -n Don't include the terminating null character that - terminates lookup keys and values. By default, - Postfix does whatever is the default for the host + -n Don't include the terminating null character that + terminates lookup keys and values. By default, + Postfix does whatever is the default for the host operating system. - -q key Search the specified maps for key and print the - first value found on the standard output stream. - The exit status is non-zero if the requested infor- - mation was not found. + -q key Search the specified maps for key and print the + first value found on the standard output stream. + The exit status is zero when the requested informa- + tion was found. + + If a key value of - is specified, the program reads + key values from the standard input stream and + prints one line of key value output for each key + that was found. The exit status is zero when at + least one of the requested keys was found. - -r When updating a table, do not warn about duplicate + -r When updating a table, do not warn about duplicate entries; silently replace them. -v Enable verbose logging for debugging purposes. Mul- - tiple -v options make the software increasingly + tiple -v options make the software increasingly verbose. - -w When updating a table, do not warn about duplicate + -w When updating a table, do not warn about duplicate entries; silently ignore them. Arguments: @@ -101,30 +112,19 @@ POSTMAP(1) POSTMAP(1) file_type The type of database to be produced. - btree The output file is a btree file, named - file_name.db. This is available only on + btree The output file is a btree file, named + file_name.db. This is available only on systems with support for db databases. - dbm The output consists of two files, named - file_name.pag and file_name.dir. This is - available only on systems with support for + dbm The output consists of two files, named + file_name.pag and file_name.dir. This is + available only on systems with support for dbm databases. - hash The output file is a hashed file, named - file_name.db. This is available only on + hash The output file is a hashed file, named + file_name.db. This is available only on systems with support for db databases. - When no file_type is specified, the software uses - the database type specified via the database_type - configuration parameter. - - file_name - The name of the lookup table source file when - rebuilding a database. - -DIAGNOSTICS - Problems and transactions are logged to the standard error - stream. No output means no problems. Duplicate entries are @@ -137,14 +137,25 @@ POSTMAP(1) POSTMAP(1) POSTMAP(1) POSTMAP(1) + When no file_type is specified, the software uses + the database type specified via the database_type + configuration parameter. + + file_name + The name of the lookup table source file when + rebuilding a database. + +DIAGNOSTICS + Problems and transactions are logged to the standard error + stream. No output means no problems. Duplicate entries are skipped and are flagged with a warning. - postmap terminates with zero exit status in case of suc- - cess (including successful postmap -q lookup) and termi- + postmap terminates with zero exit status in case of suc- + cess (including successful postmap -q lookup) and termi- nates with non-zero exit status in case of failure. BUGS - The "delete key" support is limited to one delete opera- + The "delete key" support is limited to one delete opera- tion per command invocation. ENVIRONMENT @@ -156,12 +167,12 @@ POSTMAP(1) POSTMAP(1) CONFIGURATION PARAMETERS database_type - Default output database type. On many UNIX sys- - tems, the default database type is either hash or + Default output database type. On many UNIX sys- + tems, the default database type is either hash or dbm. LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) @@ -178,17 +189,6 @@ POSTMAP(1) POSTMAP(1) - - - - - - - - - - - diff --git a/postfix/html/regexp_table.5.html b/postfix/html/regexp_table.5.html index ad38289d1..3487c922c 100644 --- a/postfix/html/regexp_table.5.html +++ b/postfix/html/regexp_table.5.html @@ -50,13 +50,13 @@ REGEXP_TABLE(5) REGEXP_TABLE(5) Other flags are `x' (disable extended expression syntax), and `m' (enable multi-line mode). - Each pattern is 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. Thus, no parent domain or parent - network search is done, and user@domain mail addresses are - not broken up into their user and domain constituent - parts, nor is user+foo broken up into user and foo. + Each pattern is applied to the entire lookup key string. + Depending on the application, that string is an entire + client hostname, an entire client IP address, or an entire + mail address. Thus, no parent domain or parent network + search is done, and user@domain mail addresses are not + broken up into their user and domain constituent parts, + nor is user+foo broken up into user and foo. Patterns are applied in the order as specified in the @@ -74,10 +74,10 @@ REGEXP_TABLE(5) REGEXP_TABLE(5) table, until a pattern is found that matches the search string. - Substitution of sub-strings from the matched expression is - possible using $1, $2, etc.. The macros in the replacement - string may need to be written as ${n} or $(n) if they - aren't followed by whitespace. + Substitution of substrings from the matched expression + into the result string is possible using $1, $2, etc.. The + macros in the result string may need to be written as ${n} + or $(n) if they aren't followed by whitespace. EXAMPLES # Disallow sender-specified routing. This is a must if you relay mail diff --git a/postfix/man/man1/postalias.1 b/postfix/man/man1/postalias.1 index 5637bbef4..1e8b32833 100644 --- a/postfix/man/man1/postalias.1 +++ b/postfix/man/man1/postalias.1 @@ -35,7 +35,11 @@ Read the \fBmain.cf\fR configuration file in the named directory instead of the default configuration directory. .IP "\fB-d \fIkey\fR" Search the specified maps for \fIkey\fR and remove one entry per map. -The exit status is non-zero if the requested information was not found. +The exit status is zero when the requested information was found. + +If a key value of \fB-\fR is specified, the program reads key +values from the standard input stream. The exit status is zero +when at least one of the requested keys was found. .IP \fB-i\fR Incremental mode. Read entries from standard input and do not truncate an existing database. By default, \fBpostalias\fR creates @@ -46,8 +50,13 @@ keys and values. By default, Postfix does whatever is the default for the host operating system. .IP "\fB-q \fIkey\fR" Search the specified maps for \fIkey\fR and print the first value -found on the standard output stream. The exit status is non-zero -if the requested information was not found. +found on the standard output stream. The exit status is zero +when the requested information was found. + +If a key value of \fB-\fR is specified, the program reads key +values from the standard input stream and prints one line of +\fIkey: value\fR output for each key that was found. The exit +status is zero when at least one of the requested keys was found. .IP \fB-r\fR When updating a table, do not warn about duplicate entries; silently replace them. diff --git a/postfix/man/man1/postmap.1 b/postfix/man/man1/postmap.1 index bdcd3bf16..2f0b9c6c1 100644 --- a/postfix/man/man1/postmap.1 +++ b/postfix/man/man1/postmap.1 @@ -53,7 +53,11 @@ Read the \fBmain.cf\fR configuration file in the named directory instead of the default configuration directory. .IP "\fB-d \fIkey\fR" Search the specified maps for \fIkey\fR and remove one entry per map. -The exit status is non-zero if the requested information was not found. +The exit status is zero when the requested information was found. + +If a key value of \fB-\fR is specified, the program reads key +values from the standard input stream. The exit status is zero +when at least one of the requested keys was found. .IP \fB-i\fR Incremental mode. Read entries from standard input and do not truncate an existing database. By default, \fBpostmap\fR creates @@ -64,8 +68,13 @@ keys and values. By default, Postfix does whatever is the default for the host operating system. .IP "\fB-q \fIkey\fR" Search the specified maps for \fIkey\fR and print the first value -found on the standard output stream. The exit status is non-zero -if the requested information was not found. +found on the standard output stream. The exit status is zero +when the requested information was found. + +If a key value of \fB-\fR is specified, the program reads key +values from the standard input stream and prints one line of +\fIkey value\fR output for each key that was found. The exit +status is zero when at least one of the requested keys was found. .IP \fB-r\fR When updating a table, do not warn about duplicate entries; silently replace them. diff --git a/postfix/man/man5/pcre_table.5 b/postfix/man/man5/pcre_table.5 index 51d59c1ee..852442305 100644 --- a/postfix/man/man5/pcre_table.5 +++ b/postfix/man/man5/pcre_table.5 @@ -41,7 +41,7 @@ are supported, but the only other useful one is `U', which makes matching ungreedy (see PCRE documentation and source for more info). -Each pattern is applied to the entire string being looked up. +Each pattern is applied to the entire lookup key string. Depending on the application, that string is an entire client hostname, an entire client IP address, or an entire mail address. Thus, no parent domain or parent network search is done, and @@ -52,9 +52,9 @@ broken up into \fIuser\fR and \fIfoo\fR. Patterns are applied in the order as specified in the table, until a pattern is found that matches the search string. -Substitution of sub-strings from the matched expression is -possible using the conventional perl syntax ($1, $2, etc.). The -macros in the replacement string may need to be written as ${n} +Substitution of substrings from the matched expression into the result +string is possible using the conventional perl syntax ($1, $2, etc.). +The macros in the result string may need to be written as ${n} or $(n) if they aren't followed by whitespace. .SH EXAMPLES .na diff --git a/postfix/man/man5/regexp_table.5 b/postfix/man/man5/regexp_table.5 index c9a9c60b2..efea3ef73 100644 --- a/postfix/man/man5/regexp_table.5 +++ b/postfix/man/man5/regexp_table.5 @@ -43,7 +43,7 @@ the second slash with an `i' flag will reverse this. Other flags are `x' (disable extended expression syntax), and `m' (enable multi-line mode). -Each pattern is applied to the entire string being looked up. +Each pattern is applied to the entire lookup key string. Depending on the application, that string is an entire client hostname, an entire client IP address, or an entire mail address. Thus, no parent domain or parent network search is done, and @@ -54,8 +54,8 @@ broken up into \fIuser\fR and \fIfoo\fR. Patterns are applied in the order as specified in the table, until a pattern is found that matches the search string. -Substitution of sub-strings from the matched expression is -possible using $1, $2, etc.. The macros in the replacement string +Substitution of substrings from the matched expression into the result +string is possible using $1, $2, etc.. The macros in the result string may need to be written as ${n} or $(n) if they aren't followed by whitespace. .SH EXAMPLES diff --git a/postfix/proto/pcre_table b/postfix/proto/pcre_table index 9ad5b9d90..7f71dcc8e 100644 --- a/postfix/proto/pcre_table +++ b/postfix/proto/pcre_table @@ -35,7 +35,7 @@ # matching ungreedy (see PCRE documentation and source for more # info). # -# Each pattern is applied to the entire string being looked up. +# Each pattern is applied to the entire lookup key string. # Depending on the application, that string is an entire client # hostname, an entire client IP address, or an entire mail address. # Thus, no parent domain or parent network search is done, and @@ -46,9 +46,9 @@ # Patterns are applied in the order as specified in the table, until a # pattern is found that matches the search string. # -# Substitution of sub-strings from the matched expression is -# possible using the conventional perl syntax ($1, $2, etc.). The -# macros in the replacement string may need to be written as ${n} +# Substitution of substrings from the matched expression into the result +# string is possible using the conventional perl syntax ($1, $2, etc.). +# The macros in the result string may need to be written as ${n} # or $(n) if they aren't followed by whitespace. # EXAMPLES # # Protect your outgoing majordomo exploders diff --git a/postfix/proto/regexp_table b/postfix/proto/regexp_table index c65e215de..bf4539404 100644 --- a/postfix/proto/regexp_table +++ b/postfix/proto/regexp_table @@ -37,7 +37,7 @@ # are `x' (disable extended expression syntax), and `m' (enable # multi-line mode). # -# Each pattern is applied to the entire string being looked up. +# Each pattern is applied to the entire lookup key string. # Depending on the application, that string is an entire client # hostname, an entire client IP address, or an entire mail address. # Thus, no parent domain or parent network search is done, and @@ -48,8 +48,8 @@ # Patterns are applied in the order as specified in the table, until a # pattern is found that matches the search string. # -# Substitution of sub-strings from the matched expression is -# possible using $1, $2, etc.. The macros in the replacement string +# Substitution of substrings from the matched expression into the result +# string is possible using $1, $2, etc.. The macros in the result string # may need to be written as ${n} or $(n) if they aren't followed # by whitespace. # EXAMPLES diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 5110c7251..00d908938 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -15,7 +15,7 @@ * Version of this program. */ #define VAR_MAIL_VERSION "mail_version" -#define DEF_MAIL_VERSION "Snapshot-20010329" +#define DEF_MAIL_VERSION "Snapshot-20010414" extern char *var_mail_version; /* LICENSE diff --git a/postfix/src/master/master.h b/postfix/src/master/master.h index 836114aae..bb32b956e 100644 --- a/postfix/src/master/master.h +++ b/postfix/src/master/master.h @@ -45,6 +45,7 @@ typedef struct MASTER_SERV { #define MASTER_FLAG_THROTTLE (1<<0) /* we're having trouble */ #define MASTER_FLAG_MARK (1<<1) /* garbage collection support */ #define MASTER_FLAG_CONDWAKE (1<<2) /* wake up if actually used */ +#define MASTER_FLAG_INETHOST (1<<3) /* endpoint name specifies host */ #define MASTER_THROTTLED(f) ((f)->flags & MASTER_FLAG_THROTTLE) diff --git a/postfix/src/master/master_ent.c b/postfix/src/master/master_ent.c index 1069e10f8..fd05bc2b6 100644 --- a/postfix/src/master/master_ent.c +++ b/postfix/src/master/master_ent.c @@ -84,6 +84,8 @@ #include #include #include +#include +#include /* Global library. */ @@ -222,6 +224,8 @@ MASTER_SERV *get_master_ent() MASTER_SERV *serv; char *cp; char *name; + char *host; + char *port; char *transport; int private; int unprivileged; /* passed on to child */ @@ -229,6 +233,7 @@ MASTER_SERV *get_master_ent() char *command; int n; char *bufp; + char *atmp; if (master_fp == 0) msg_panic("get_master_ent: config file not open"); @@ -270,13 +275,22 @@ MASTER_SERV *get_master_ent() transport = get_str_ent(&bufp, "transport type", (char *) 0); if (STR_SAME(transport, MASTER_XPORT_NAME_INET)) { serv->type = MASTER_SERV_TYPE_INET; - if (strcasecmp(var_inet_interfaces, DEF_INET_INTERFACES) == 0) { + atmp = inet_parse(name, &host, &port); + if (host && *host) { + serv->flags |= MASTER_FLAG_INETHOST; + serv->addr_list.inet = + (INET_ADDR_LIST *) mymalloc(sizeof(*serv->addr_list_buf.inet)); + inet_addr_list_init(serv->addr_list.inet); + inet_addr_host(serv->addr_list.inet, host); + serv->listen_fd_count = serv->addr_list.inet->used; + } else if (strcasecmp(var_inet_interfaces, DEF_INET_INTERFACES) == 0) { serv->addr_list.inet = 0; /* wild-card */ serv->listen_fd_count = 1; } else { serv->addr_list.inet = own_inet_addr_list(); /* virtual */ serv->listen_fd_count = serv->addr_list.inet->used; } + myfree(atmp); } else if (STR_SAME(transport, MASTER_XPORT_NAME_UNIX)) { serv->type = MASTER_SERV_TYPE_UNIX; serv->listen_fd_count = 1; @@ -449,6 +463,8 @@ void free_master_ent(MASTER_SERV *serv) /* * Undo what get_master_ent() created. */ + if (serv->flags & MASTER_FLAG_INETHOST) + inet_addr_list_free(serv->addr_list.inet); myfree(serv->name); myfree(serv->path); argv_free(serv->args); diff --git a/postfix/src/postalias/postalias.c b/postfix/src/postalias/postalias.c index 0fe46f910..221254809 100644 --- a/postfix/src/postalias/postalias.c +++ b/postfix/src/postalias/postalias.c @@ -29,7 +29,11 @@ /* instead of the default configuration directory. /* .IP "\fB-d \fIkey\fR" /* Search the specified maps for \fIkey\fR and remove one entry per map. -/* The exit status is non-zero if the requested information was not found. +/* The exit status is zero when the requested information was found. +/* +/* If a key value of \fB-\fR is specified, the program reads key +/* values from the standard input stream. The exit status is zero +/* when at least one of the requested keys was found. /* .IP \fB-i\fR /* Incremental mode. Read entries from standard input and do not /* truncate an existing database. By default, \fBpostalias\fR creates @@ -40,8 +44,13 @@ /* the host operating system. /* .IP "\fB-q \fIkey\fR" /* Search the specified maps for \fIkey\fR and print the first value -/* found on the standard output stream. The exit status is non-zero -/* if the requested information was not found. +/* found on the standard output stream. The exit status is zero +/* when the requested information was found. +/* +/* If a key value of \fB-\fR is specified, the program reads key +/* values from the standard input stream and prints one line of +/* \fIkey: value\fR output for each key that was found. The exit +/* status is zero when at least one of the requested keys was found. /* .IP \fB-r\fR /* When updating a table, do not warn about duplicate entries; silently /* replace them. @@ -137,6 +146,7 @@ #include #include #include +#include /* Global library. */ @@ -306,6 +316,62 @@ static void postalias(char *map_type, char *path_name, vstream_fclose(source_fp); } +/* postalias_queries - apply multiple requests from stdin */ + +static int postalias_queries(VSTREAM *in, char **maps, const int map_count) +{ + int found = 0; + VSTRING *keybuf = vstring_alloc(100); + DICT **dicts; + const char *map_name; + const char *value; + int n; + + /* + * Sanity check. + */ + if (map_count <= 0) + msg_panic("postalias_queries: bad map count"); + + /* + * Prepare to open maps lazily. + */ + dicts = (DICT **) mymalloc(sizeof(*dicts) * map_count); + for (n = 0; n < map_count; n++) + dicts[n] = 0; + + /* + * Perform all queries. Open maps on the fly, to avoid opening unecessary + * maps. + */ + while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) { + for (n = 0; n < map_count; n++) { + if (dicts[n] == 0) + dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ? + dict_open3(maps[n], map_name, O_RDONLY, DICT_FLAG_LOCK) : + dict_open3(var_db_type, maps[n], O_RDONLY, DICT_FLAG_LOCK)); + if ((value = dict_get(dicts[n], STR(keybuf))) != 0) { + vstream_printf("%s: %s\n", STR(keybuf), value); + found = 1; + break; + } + } + } + if (found) + vstream_fflush(VSTREAM_OUT); + + /* + * Cleanup. + */ + for (n = 0; n < map_count; n++) + if (dicts[n]) + dict_close(dicts[n]); + myfree((char *) dicts); + vstring_free(keybuf); + + return (found); +} + /* postalias_query - query a map and print the result to stdout */ static int postalias_query(const char *map_type, const char *map_name, @@ -323,6 +389,50 @@ static int postalias_query(const char *map_type, const char *map_name, return (value != 0); } +/* postalias_deletes - apply multiple requests from stdin */ + +static int postalias_deletes(VSTREAM *in, char **maps, const int map_count) +{ + int found = 0; + VSTRING *keybuf = vstring_alloc(100); + DICT **dicts; + const char *map_name; + int n; + + /* + * Sanity check. + */ + if (map_count <= 0) + msg_panic("postalias_deletes: bad map count"); + + /* + * Open maps ahead of time. + */ + dicts = (DICT **) mymalloc(sizeof(*dicts) * map_count); + for (n = 0; n < map_count; n++) + dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ? + dict_open3(maps[n], map_name, O_RDWR, DICT_FLAG_LOCK) : + dict_open3(var_db_type, maps[n], O_RDWR, DICT_FLAG_LOCK)); + + /* + * Perform all requests. + */ + while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) + for (n = 0; n < map_count; n++) + found |= (dict_del(dicts[n], STR(keybuf)) == 0); + + /* + * Cleanup. + */ + for (n = 0; n < map_count; n++) + if (dicts[n]) + dict_close(dicts[n]); + myfree((char *) dicts); + vstring_free(keybuf); + + return (found); +} + /* postalias_delete - delete a key value pair from a map */ static int postalias_delete(const char *map_type, const char *map_name, @@ -331,10 +441,6 @@ static int postalias_delete(const char *map_type, const char *map_name, DICT *dict; int status; - /* - * XXX This must be generalized to multi-key (read from stdin) and - * multi-map (given on command line) updates. - */ dict = dict_open3(map_type, map_name, O_RDWR, DICT_FLAG_LOCK); status = dict_del(dict, key); dict_close(dict); @@ -447,6 +553,8 @@ int main(int argc, char **argv) if (delkey) { /* remove entry */ if (optind + 1 > argc) usage(argv[0]); + if (strcmp(delkey, "-") == 0) + exit(postalias_deletes(VSTREAM_IN, argv + optind, argc - optind) == 0); found = 0; while (optind < argc) { if ((path_name = split_at(argv[optind], ':')) != 0) { @@ -460,6 +568,8 @@ int main(int argc, char **argv) } else if (query) { /* query map(s) */ if (optind + 1 > argc) usage(argv[0]); + if (strcmp(query, "-") == 0) + exit(postalias_queries(VSTREAM_IN, argv + optind, argc - optind) == 0); while (optind < argc) { if ((path_name = split_at(argv[optind], ':')) != 0) { found = postalias_query(argv[optind], path_name, query); diff --git a/postfix/src/postmap/postmap.c b/postfix/src/postmap/postmap.c index f82edfb14..aac5b1f69 100644 --- a/postfix/src/postmap/postmap.c +++ b/postfix/src/postmap/postmap.c @@ -47,7 +47,11 @@ /* instead of the default configuration directory. /* .IP "\fB-d \fIkey\fR" /* Search the specified maps for \fIkey\fR and remove one entry per map. -/* The exit status is non-zero if the requested information was not found. +/* The exit status is zero when the requested information was found. +/* +/* If a key value of \fB-\fR is specified, the program reads key +/* values from the standard input stream. The exit status is zero +/* when at least one of the requested keys was found. /* .IP \fB-i\fR /* Incremental mode. Read entries from standard input and do not /* truncate an existing database. By default, \fBpostmap\fR creates @@ -58,8 +62,13 @@ /* the host operating system. /* .IP "\fB-q \fIkey\fR" /* Search the specified maps for \fIkey\fR and print the first value -/* found on the standard output stream. The exit status is non-zero -/* if the requested information was not found. +/* found on the standard output stream. The exit status is zero +/* when the requested information was found. +/* +/* If a key value of \fB-\fR is specified, the program reads key +/* values from the standard input stream and prints one line of +/* \fIkey value\fR output for each key that was found. The exit +/* status is zero when at least one of the requested keys was found. /* .IP \fB-r\fR /* When updating a table, do not warn about duplicate entries; silently /* replace them. @@ -146,6 +155,7 @@ #include #include #include +#include /* Global library. */ @@ -253,6 +263,62 @@ static void postmap(char *map_type, char *path_name, vstream_fclose(source_fp); } +/* postmap_queries - apply multiple requests from stdin */ + +static int postmap_queries(VSTREAM *in, char **maps, const int map_count) +{ + int found = 0; + VSTRING *keybuf = vstring_alloc(100); + DICT **dicts; + const char *map_name; + const char *value; + int n; + + /* + * Sanity check. + */ + if (map_count <= 0) + msg_panic("postmap_queries: bad map count"); + + /* + * Prepare to open maps lazily. + */ + dicts = (DICT **) mymalloc(sizeof(*dicts) * map_count); + for (n = 0; n < map_count; n++) + dicts[n] = 0; + + /* + * Perform all queries. Open maps on the fly, to avoid opening unecessary + * maps. + */ + while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) { + for (n = 0; n < map_count; n++) { + if (dicts[n] == 0) + dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ? + dict_open3(maps[n], map_name, O_RDONLY, DICT_FLAG_LOCK) : + dict_open3(var_db_type, maps[n], O_RDONLY, DICT_FLAG_LOCK)); + if ((value = dict_get(dicts[n], STR(keybuf))) != 0) { + vstream_printf("%s %s\n", STR(keybuf), value); + found = 1; + break; + } + } + } + if (found) + vstream_fflush(VSTREAM_OUT); + + /* + * Cleanup. + */ + for (n = 0; n < map_count; n++) + if (dicts[n]) + dict_close(dicts[n]); + myfree((char *) dicts); + vstring_free(keybuf); + + return (found); +} + /* postmap_query - query a map and print the result to stdout */ static int postmap_query(const char *map_type, const char *map_name, @@ -270,6 +336,50 @@ static int postmap_query(const char *map_type, const char *map_name, return (value != 0); } +/* postmap_deletes - apply multiple requests from stdin */ + +static int postmap_deletes(VSTREAM *in, char **maps, const int map_count) +{ + int found = 0; + VSTRING *keybuf = vstring_alloc(100); + DICT **dicts; + const char *map_name; + int n; + + /* + * Sanity check. + */ + if (map_count <= 0) + msg_panic("postmap_deletes: bad map count"); + + /* + * Open maps ahead of time. + */ + dicts = (DICT **) mymalloc(sizeof(*dicts) * map_count); + for (n = 0; n < map_count; n++) + dicts[n] = ((map_name = split_at(maps[n], ':')) != 0 ? + dict_open3(maps[n], map_name, O_RDWR, DICT_FLAG_LOCK) : + dict_open3(var_db_type, maps[n], O_RDWR, DICT_FLAG_LOCK)); + + /* + * Perform all requests. + */ + while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) + for (n = 0; n < map_count; n++) + found |= (dict_del(dicts[n], STR(keybuf)) == 0); + + /* + * Cleanup. + */ + for (n = 0; n < map_count; n++) + if (dicts[n]) + dict_close(dicts[n]); + myfree((char *) dicts); + vstring_free(keybuf); + + return (found); +} + /* postmap_delete - delete a (key, value) pair from a map */ static int postmap_delete(const char *map_type, const char *map_name, @@ -278,10 +388,6 @@ static int postmap_delete(const char *map_type, const char *map_name, DICT *dict; int status; - /* - * XXX This must be generalized to multi-key (read from stdin) and - * multi-map (given on command line) updates. - */ dict = dict_open3(map_type, map_name, O_RDWR, DICT_FLAG_LOCK); status = dict_del(dict, key); dict_close(dict); @@ -394,6 +500,8 @@ int main(int argc, char **argv) if (delkey) { /* remove entry */ if (optind + 1 > argc) usage(argv[0]); + if (strcmp(delkey, "-") == 0) + exit(postmap_deletes(VSTREAM_IN, argv + optind, argc - optind) == 0); found = 0; while (optind < argc) { if ((path_name = split_at(argv[optind], ':')) != 0) { @@ -407,6 +515,8 @@ int main(int argc, char **argv) } else if (query) { /* query map(s) */ if (optind + 1 > argc) usage(argv[0]); + if (strcmp(query, "-") == 0) + exit(postmap_queries(VSTREAM_IN, argv + optind, argc - optind) == 0); while (optind < argc) { if ((path_name = split_at(argv[optind], ':')) != 0) { found = postmap_query(argv[optind], path_name, query); diff --git a/postfix/src/smtp/smtp_addr.c b/postfix/src/smtp/smtp_addr.c index c9109fa3a..2a6a9d12a 100644 --- a/postfix/src/smtp/smtp_addr.c +++ b/postfix/src/smtp/smtp_addr.c @@ -354,6 +354,8 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why, int *found_myself) } else if (*var_bestmx_transp != 0) { /* we're best MX */ smtp_errno = SMTP_OK; } else { + msg_warn("mailer loop: best MX host for %s is local", + name); vstring_sprintf(why, "mail for %s loops back to myself", name); smtp_errno = SMTP_FAIL; diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 3de90461a..6822cd1a4 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -823,9 +823,12 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) * error. */ if (state->rcpt_count == 0) { - if (state->cleanup == 0) + if (state->cleanup == 0) { state->error_mask |= MAIL_ERROR_PROTOCOL; - smtpd_chat_reply(state, "503 Error: need RCPT command"); + smtpd_chat_reply(state, "503 Error: need RCPT command"); + } else { + smtpd_chat_reply(state, "550 Error: no valid recipients"); + } return (-1); } if (argc != 1) { diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c index 32187d3f7..aaac7988e 100644 --- a/postfix/src/smtpd/smtpd_check.c +++ b/postfix/src/smtpd/smtpd_check.c @@ -1440,6 +1440,14 @@ static int reject_maps_rbl(SMTPD_STATE *state) if (msg_verbose) msg_info("%s: %s", myname, state->addr); + /* + * IPv4 only for now + */ +#ifdef INET6 + if (inet_pton(AF_INET, state->addr, &a) != 1) + return SMTPD_CHECK_DUNNO; +#endif + /* * Build the constant part of the RBL query: the reverse client address. */ diff --git a/postfix/src/util/dict_db.c b/postfix/src/util/dict_db.c index 02b72baf4..69518e10f 100644 --- a/postfix/src/util/dict_db.c +++ b/postfix/src/util/dict_db.c @@ -439,6 +439,13 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags, db_path = concatenate(path, ".db", (char *) 0); + /* + * Note: DICT_FLAG_LOCK is used only by programs that do fine-grained (in + * the time domain) locking while accessing individual database records. + * + * Programs such as postmap/postalias use their own large-grained (in the + * time domain) locks while rewriting the entire file. + */ if (dict_flags & DICT_FLAG_LOCK) { if ((lock_fd = open(db_path, open_flags, 0644)) < 0) msg_fatal("open database %s: %m", db_path); @@ -517,13 +524,24 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags, if (fstat(dict_db->dict.fd, &st) < 0) msg_fatal("dict_db_open: fstat: %m"); dict_db->dict.mtime = st.st_mtime; + + /* + * Warn if the source file is newer than the indexed file, except when + * the source file changed only seconds ago. + */ + if ((dict_flags & DICT_FLAG_LOCK) != 0 + && stat(path, &st) == 0 + && st.st_mtime > dict_db->dict.mtime + && st.st_mtime < time((time_t *) 0) - 100) + msg_warn("database %s is older than source file %s", db_path, path); + close_on_exec(dict_db->dict.fd, CLOSE_ON_EXEC); dict_db->dict.flags = dict_flags | DICT_FLAG_FIXED; if ((dict_flags & (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL)) == 0) dict_db->dict.flags |= (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL); dict_db->db = db; myfree(db_path); - return (DICT_DEBUG(&dict_db->dict)); + return (DICT_DEBUG (&dict_db->dict)); } /* dict_hash_open - create association with data base */ diff --git a/postfix/src/util/dict_dbm.c b/postfix/src/util/dict_dbm.c index 6f3a5611a..575d5eb54 100644 --- a/postfix/src/util/dict_dbm.c +++ b/postfix/src/util/dict_dbm.c @@ -371,6 +371,13 @@ DICT *dict_dbm_open(const char *path, int open_flags, int dict_flags) char *dbm_path; int lock_fd; + /* + * Note: DICT_FLAG_LOCK is used only by programs that do fine-grained (in + * the time domain) locking while accessing individual database records. + * + * Programs such as postmap/postalias use their own large-grained (in the + * time domain) locks while rewriting the entire file. + */ if (dict_flags & DICT_FLAG_LOCK) { dbm_path = concatenate(path, ".pag", (char *) 0); if ((lock_fd = open(dbm_path, open_flags, 0644)) < 0) @@ -390,7 +397,6 @@ DICT *dict_dbm_open(const char *path, int open_flags, int dict_flags) msg_fatal("unlock database %s for open: %m", dbm_path); if (close(lock_fd) < 0) msg_fatal("close database %s: %m", dbm_path); - myfree(dbm_path); } dict_dbm = (DICT_DBM *) dict_alloc(DICT_TYPE_DBM, path, sizeof(*dict_dbm)); dict_dbm->dict.lookup = dict_dbm_lookup; @@ -402,6 +408,17 @@ DICT *dict_dbm_open(const char *path, int open_flags, int dict_flags) if (fstat(dict_dbm->dict.fd, &st) < 0) msg_fatal("dict_dbm_open: fstat: %m"); dict_dbm->dict.mtime = st.st_mtime; + + /* + * Warn if the source file is newer than the indexed file, except when + * the source file changed only seconds ago. + */ + if ((dict_flags & DICT_FLAG_LOCK) != 0 + && stat(path, &st) == 0 + && st.st_mtime > dict_dbm->dict.mtime + && st.st_mtime < time((time_t *) 0) - 100) + msg_warn("database %s is older than source file %s", dbm_path, path); + close_on_exec(dbm_pagfno(dbm), CLOSE_ON_EXEC); close_on_exec(dbm_dirfno(dbm), CLOSE_ON_EXEC); dict_dbm->dict.flags = dict_flags | DICT_FLAG_FIXED; @@ -409,7 +426,10 @@ DICT *dict_dbm_open(const char *path, int open_flags, int dict_flags) dict_dbm->dict.flags |= (DICT_FLAG_TRY0NULL | DICT_FLAG_TRY1NULL); dict_dbm->dbm = dbm; - return (DICT_DEBUG(&dict_dbm->dict)); + if ((dict_flags & DICT_FLAG_LOCK)) + myfree(dbm_path); + + return (DICT_DEBUG (&dict_dbm->dict)); } #endif diff --git a/postfix/src/util/dict_ldap.c b/postfix/src/util/dict_ldap.c index fc3a80213..44b121d81 100644 --- a/postfix/src/util/dict_ldap.c +++ b/postfix/src/util/dict_ldap.c @@ -297,7 +297,8 @@ static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage * res, entry = ldap_next_entry(dict_ldap->ld, entry)) { attr = ldap_first_attribute(dict_ldap->ld, entry, &ber); if (attr == NULL) { - msg_warn("%s: no attributes found", myname); + if (msg_verbose) + msg_info("%s: no attributes found", myname); continue; } for (; attr != NULL; @@ -305,8 +306,9 @@ static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage * res, vals = ldap_get_values(dict_ldap->ld, entry, attr); if (vals == NULL) { - msg_warn("%s: Entry doesn't have any values for %s", - myname, attr); + if (msg_verbose) + msg_info("%s: Entry doesn't have any values for %s", + myname, attr); continue; } for (i = 0; dict_ldap->result_attributes->argv[i]; i++) { diff --git a/postfix/src/util/dict_mysql.c b/postfix/src/util/dict_mysql.c index d16c90c85..28fc70156 100644 --- a/postfix/src/util/dict_mysql.c +++ b/postfix/src/util/dict_mysql.c @@ -201,6 +201,12 @@ static const char *dict_mysql_lookup(DICT *dict, const char *name) if (i > 0) vstring_strcat(result, ","); for (j = 0; j < mysql_num_fields(query_res); j++) { + if (row[j] == 0) { + if (msg_verbose > 1) + msg_info("dict_mysql_lookup: null field #%d row #%d", j, i); + mysql_free_result(query_res); + return (0); + } if (j > 0) vstring_strcat(result, ","); vstring_strcat(result, row[j]);