From: Wietse Venema Date: Sat, 28 Oct 2000 05:00:00 +0000 (-0500) Subject: snapshot-20001028 X-Git-Tag: v20010228~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=273b2bb4498e4656c72fa68af2f242ae51235657;p=thirdparty%2Fpostfix.git snapshot-20001028 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 937faa4f1..f29bd449b 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -4354,13 +4354,14 @@ Apologies for any names omitted. Portability: Redhat 7 library interfaces have changed incompatibly, which breaks existing software. File makedefs. - Bugfix: the fallback_relay parameter did not work with [] - or with network ports, and Postfix would always attempt to - perform MX record lookups. Files: smtp/smtp_addr.c + Consistency: the fallback_relay parameter did not understand + the [] or host:port syntax, and there was no way to suppress + MX record lookups. Files: smtp/smtp_addr.c, smtp/smtp_connect.c. Convenience: you can now specify multiple destinations in - the relayhost configuration parameter. They will be tried - in the specified order. File: smtp/smtp_connect.c. + the relayhost or fallback_relay configuration parameters. + The specified destinations will be tried in the specified + order. File: smtp/smtp_connect.c. Typographical corrections by Matthias Andree. @@ -4387,11 +4388,11 @@ Apologies for any names omitted. now supports three Berkeley DB programming interfaces of increasing complexity. File: util/dict_db.c. - Bugfix: made some character manipulations independent of + Bugfix: some character manipulations were not portable for signed/unsigned characters. Files: global/quote_821_local.c, global/quote_822_local.c. - Workaround: some software sends SMTP mail that begins with - "From sender time-stamp". Sendmail accepts such RFC vioating - garbage, and therefore Postfix needs to jump another hoop. - File: smtpd/smtpd.c. + Workaround: apparently, some software sends SMTP mail that + begins with "From sender time-stamp". Sendmail silently + ignores such RFC violating garbage, and therefore Postfix + needs to jump another hoop. File: smtpd/smtpd.c. diff --git a/postfix/conf/main.cf b/postfix/conf/main.cf index 659e0ef64..e96e68d54 100644 --- a/postfix/conf/main.cf +++ b/postfix/conf/main.cf @@ -355,8 +355,8 @@ mail_owner = postfix # SMTP "ETRN domain.name" command, or after execution of "sendmail # -qRdomain.name". This can be slow when a lot of mail is queued. # -# The fast_flush_domains controls what destinations are eligible for -# this "fast ETRN/sendmail -qR" service. +# The fast_flush_domains parameter controls what destinations are +# eligible for this "fast ETRN/sendmail -qR" service. # #fast_flush_domains = $relay_domains #fast_flush_policy = diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 52962ac12..88662d95e 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-20001027" +#define DEF_MAIL_VERSION "Snapshot-20001028" extern char *var_mail_version; /* LICENSE diff --git a/postfix/src/postfix/postfix.c b/postfix/src/postfix/postfix.c index 1fb4c399f..466118504 100644 --- a/postfix/src/postfix/postfix.c +++ b/postfix/src/postfix/postfix.c @@ -174,7 +174,7 @@ int main(int argc, char **argv) */ if ((uid = getuid()) != 0) { msg_error("to submit mail, use the Postfix sendmail command"); - msg_fatal("the postfix command must be run by the superuser"); + msg_fatal("the postfix command is reserved for the superuser"); } /* diff --git a/postfix/src/util/dict.h b/postfix/src/util/dict.h index 2173cf607..c5d2b9162 100644 --- a/postfix/src/util/dict.h +++ b/postfix/src/util/dict.h @@ -50,6 +50,7 @@ typedef struct DICT { extern int dict_unknown_allowed; extern int dict_errno; +#define DICT_ERR_NONE 0 /* no error */ #define DICT_ERR_RETRY 1 /* soft error */ /* diff --git a/postfix/src/util/dict_tcp.c b/postfix/src/util/dict_tcp.c index 4abf3ba47..ccb516292 100644 --- a/postfix/src/util/dict_tcp.c +++ b/postfix/src/util/dict_tcp.c @@ -14,43 +14,54 @@ /* dict_tcp_open() makes a TCP server accessible via the generic /* dictionary operations described in dict_open(3). /* The \fIdummy\fR argument is not used. The only implemented -/* operation is dictionary lookup. +/* operation is dictionary lookup. This map type can be useful +/* for simulating a dynamic lookup table. /* /* Map names have the form host:port. /* /* The TCP map class implements a very simple protocol: the client -/* sends a query, and the server sends one reply. Queries and +/* sends a request, and the server sends one reply. Requests and /* replies are sent as one line of ASCII text, terminated by the -/* ASCII newline character. Query and reply parameters (see below) +/* ASCII newline character. Request and reply parameters (see below) /* are separated by whitespace. -/* -/* In query and reply parameters, the character % and any non-printable +/* ENCODING +/* .ad +/* .fi +/* In request and reply parameters, the character % and any non-printable /* characters (including whitespace) are replaced by %XX, XX being the /* corresponding ASCII hexadecimal character value. The hexadecimal codes /* can be specified in any case (upper, lower, mixed). -/* -/* Queries are strings that serve as lookup key in the simulated +/* REQUEST FORMAT +/* .ad +/* .fi +/* Requests are strings that serve as lookup key in the simulated /* table. /* .IP "get SPACE key NEWLINE" /* Look up data under the specified key. /* .IP "put SPACE key SPACE value NEWLINE" -/* -/* .PP +/* This request is currently not implemented. +/* REPLY FORMAT +/* .ad +/* .fi /* Replies can have the following form: -/* .IP "500 SPACE text NEWLINE" -/* The requested data does not exist. The text is ignored. -/* .IP "400 SPACE text NEWLINE" +/* .IP "500 SPACE optional-text NEWLINE" +/* In case of a lookup request, the requested data does not exist. +/* In case of an update request, the request was rejected. +/* .IP "400 SPACE optional-text NEWLINE" /* This indicates an error condition. The text gives the nature of -/* the problem. +/* the problem. The client should retry the request later. /* .IP "200 SPACE text NEWLINE" -/* The requested data was found. The text contains an encoded version -/* of the requested data. +/* The request was successful. In the case of a lookup request, +/* the text contains an encoded version of the requested data. +/* Otherwise the text is optional. /* SEE ALSO /* dict(3) generic dictionary manager /* hex_quote(3) http-style quoting /* DIAGNOSTICS /* Fatal errors: out of memory, unknown host or service name, /* attempt to update or iterate over map. +/* BUGS +/* Only the lookup method is currently implemented. /* LICENSE /* .ad /* .fi @@ -135,69 +146,97 @@ static void dict_tcp_disconnect(DICT_TCP *dict_tcp) dict_tcp->fp = 0; } -/* dict_tcp_lookup - query TCP server */ +/* dict_tcp_lookup - request TCP server */ static const char *dict_tcp_lookup(DICT *dict, const char *key) { DICT_TCP *dict_tcp = (DICT_TCP *) dict; - int i; + char *myname = "dict_tcp_lookup"; + int tries; + char *start; - dict_errno = 0; +#define RETURN(errval, result) { dict_errno = errval; return (result); } + + if (msg_verbose) + msg_info("%s: key %s", myname, key); - for (i = 0; /* see below */ ; i++) { + for (tries = 0; /* see below */ ; /* see below */ ) { /* - * Try to connect a limited number of times before giving up. + * Connect to the server, or use an existing connection. */ - if (i >= DICT_TCP_MAXTRY) { - dict_errno = DICT_ERR_RETRY; - return (0); + if (dict_tcp->fp != 0 || dict_tcp_connect(dict_tcp) == 0) { + + /* + * Send request and receive response. Both are %XX quoted and + * both are terminated by newline. This encoding is convenient + * for data that is mostly text. + */ + hex_quote(dict_tcp->hex_buf, key); + vstream_fprintf(dict_tcp->fp, "get %s\n", STR(dict_tcp->hex_buf)); + if (vstring_get_nonl(dict_tcp->hex_buf, dict_tcp->fp) > 0) + break; + + /* + * Disconnect from the server if it can't talk to us. + */ + msg_warn("read TCP map reply from %s: unexpected EOF (%m)", + dict_tcp->map); + dict_tcp_disconnect(dict_tcp); } /* - * Sleep between attempts, instead of hammering the server. + * Try to connect a limited number of times before giving up. */ - if (i > 0) - sleep(1); + if (++tries >= DICT_TCP_MAXTRY) + RETURN(DICT_ERR_RETRY, 0); /* - * Connect to the server. + * Sleep between attempts, instead of hammering the server. */ - if (dict_tcp->fp == 0) - if (dict_tcp_connect(dict_tcp) < 0) - continue; + sleep(1); + } - /* - * Send query and receive response. Both are %XX quoted and both are - * terminated by newline. This encoding is convenient for data that - * is mostly text. - */ - hex_quote(dict_tcp->hex_buf, key); - vstream_fprintf(dict_tcp->fp, "get %s\n", STR(dict_tcp->hex_buf)); - errno = 0; - if (vstring_get_nonl(dict_tcp->hex_buf, dict_tcp->fp) == VSTREAM_EOF) { - msg_warn("read TCP map reply from %s: %m", dict_tcp->map); - } else if (!hex_unquote(dict_tcp->raw_buf, STR(dict_tcp->hex_buf))) { - msg_warn("read TCP map reply from %s: malformed reply %.100s", - dict_tcp->map, - printable(STR(dict_tcp->hex_buf), '_')); - dict_errno = DICT_ERR_RETRY; - return (0); - } else if (ISSPACE(*STR(dict_tcp->raw_buf))) { - msg_warn("TCP map reply from %s failed%s%s", - dict_tcp->map, - STR(dict_tcp->raw_buf)[1] ? ":" : "", - printable(STR(dict_tcp->raw_buf), '_')); - dict_errno = DICT_ERR_RETRY; - return (0); - } else { - return (STR(dict_tcp->raw_buf)); - } + /* + * Check the general reply syntax. If the reply is malformed, disconnect + * and try again later. + */ + if (start = STR(dict_tcp->hex_buf), + !ISDIGIT(start[0]) || !ISDIGIT(start[1]) + || !ISDIGIT(start[2]) || !ISSPACE(start[3]) + || !hex_unquote(dict_tcp->raw_buf, start + 4)) { + msg_warn("read TCP map reply from %s: malformed reply %.100s", + dict_tcp->map, printable(STR(dict_tcp->hex_buf), '_')); + dict_tcp_disconnect(dict_tcp); + RETURN(DICT_ERR_RETRY, 0); + } - /* - * That did not work. Clean up and try again. - */ + /* + * Examine the reply status code. If the reply is malformed, disconnect + * and try again later. + */ + switch (start[0]) { + default: + msg_warn("read TCP map reply from %s: bad status code %.100s", + dict_tcp->map, printable(STR(dict_tcp->hex_buf), '_')); + dict_tcp_disconnect(dict_tcp); + RETURN(DICT_ERR_RETRY, 0); + case '4': + if (msg_verbose) + msg_info("%s: soft error: %s", + myname, printable(STR(dict_tcp->raw_buf), '_')); dict_tcp_disconnect(dict_tcp); + RETURN(DICT_ERR_RETRY, 0); + case '5': + if (msg_verbose) + msg_info("%s: not found: %s", + myname, printable(STR(dict_tcp->raw_buf), '_')); + RETURN(DICT_ERR_NONE, 0); + case '2': + if (msg_verbose) + msg_info("%s: found: %s", + myname, printable(STR(dict_tcp->raw_buf), '_')); + RETURN(DICT_ERR_NONE, STR(dict_tcp->raw_buf)); } } diff --git a/postfix/src/util/hex_quote.c b/postfix/src/util/hex_quote.c index 639ff74c4..f82a92001 100644 --- a/postfix/src/util/hex_quote.c +++ b/postfix/src/util/hex_quote.c @@ -20,7 +20,7 @@ /* value is the hex argument. /* /* hex_unquote() performs the opposite transformation. This function -/* understands, lowercase, uppercase, and mixed case %XX sequences. The +/* understands lowercase, uppercase, and mixed case %XX sequences. The /* result value is the raw argument in case of success, a null pointer /* otherwise. /* BUGS