summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authoritojun <itojun@NetBSD.org>2002-06-08 22:37:07 +0000
committeritojun <itojun@NetBSD.org>2002-06-08 22:37:07 +0000
commit4a4a5f078294ab7d6c2c8926db43159e7673daec (patch)
tree941afff1dcb247fc805a2b2382bda1381f5c7720 /gnu
parentd7d4214831e4287ca9b8b1dfaad1f40080d1f4b0 (diff)
postfix 1.1.11
check following for list of changes: ftp://ftp.porcupine.org/mirrors/postfix-release/official/postfix-1.1.11.RELEASE_NOTES
Diffstat (limited to 'gnu')
-rw-r--r--gnu/dist/postfix/src/qmqpd/Makefile.in1
-rw-r--r--gnu/dist/postfix/src/qmqpd/qmqpd.c2
-rw-r--r--gnu/dist/postfix/src/sendmail/sendmail.c12
-rw-r--r--gnu/dist/postfix/src/showq/Makefile.in3
-rw-r--r--gnu/dist/postfix/src/showq/showq.c36
-rw-r--r--gnu/dist/postfix/src/smtp/Makefile.in1
-rw-r--r--gnu/dist/postfix/src/smtp/smtp.c10
-rw-r--r--gnu/dist/postfix/src/smtp/smtp_proto.c90
-rw-r--r--gnu/dist/postfix/src/trivial-rewrite/Makefile.in1
-rw-r--r--gnu/dist/postfix/src/trivial-rewrite/resolve.c12
-rw-r--r--gnu/dist/postfix/src/trivial-rewrite/rewrite.c3
-rw-r--r--gnu/dist/postfix/src/trivial-rewrite/trivial-rewrite.c14
-rw-r--r--gnu/dist/postfix/src/util/dict.c4
-rw-r--r--gnu/dist/postfix/src/util/dict.h3
-rw-r--r--gnu/dist/postfix/src/util/dict_alloc.c3
-rw-r--r--gnu/dist/postfix/src/util/dict_db.c24
-rw-r--r--gnu/dist/postfix/src/util/dict_dbm.c25
-rw-r--r--gnu/dist/postfix/src/util/dict_ldap.c2
-rw-r--r--gnu/dist/postfix/src/util/strcasecmp.c66
19 files changed, 241 insertions, 71 deletions
diff --git a/gnu/dist/postfix/src/qmqpd/Makefile.in b/gnu/dist/postfix/src/qmqpd/Makefile.in
index 5e923c5b071..53703cb95fe 100644
--- a/gnu/dist/postfix/src/qmqpd/Makefile.in
+++ b/gnu/dist/postfix/src/qmqpd/Makefile.in
@@ -92,6 +92,7 @@ qmqpd.o: ../../include/namadr_list.h
qmqpd.o: ../../include/match_list.h
qmqpd.o: ../../include/match_ops.h
qmqpd.o: ../../include/quote_822_local.h
+qmqpd.o: ../../include/quote_flags.h
qmqpd.o: ../../include/match_parent_style.h
qmqpd.o: ../../include/mail_server.h
qmqpd.o: qmqpd.h
diff --git a/gnu/dist/postfix/src/qmqpd/qmqpd.c b/gnu/dist/postfix/src/qmqpd/qmqpd.c
index 0e1d472df13..92c7d9f5d75 100644
--- a/gnu/dist/postfix/src/qmqpd/qmqpd.c
+++ b/gnu/dist/postfix/src/qmqpd/qmqpd.c
@@ -364,7 +364,7 @@ static void qmqpd_write_content(QMQPD_STATE *state)
if (first) {
if (strncmp(start + strspn(start, ">"), "From ", 5) == 0) {
rec_fprintf(state->cleanup, rec_type,
- "Mailbox-Line: %*s", len, start);
+ "X-Mailbox-Line: %*s", len, start);
continue;
}
first = 0;
diff --git a/gnu/dist/postfix/src/sendmail/sendmail.c b/gnu/dist/postfix/src/sendmail/sendmail.c
index ca06eb0a3a1..ea054f656aa 100644
--- a/gnu/dist/postfix/src/sendmail/sendmail.c
+++ b/gnu/dist/postfix/src/sendmail/sendmail.c
@@ -105,6 +105,10 @@
/* .IP \fB-bs\fR
/* Stand-alone SMTP server mode. Read SMTP commands from
/* standard input, and write responses to standard output.
+/* In stand-alone SMTP server mode, UCE restrictions and
+/* access controls are disabled by default. To enable them,
+/* run the process as the \fBmail_owner\fR user.
+/* .sp
/* This mode of operation is implemented by running the
/* \fBsmtpd\fR(8) daemon.
/* .IP "\fB-f \fIsender\fR"
@@ -363,6 +367,7 @@ static void enqueue(const int flags, const char *sender, const char *full_name,
uid_t uid = getuid();
int status;
int naddr;
+ int prev_type;
/*
* Initialize.
@@ -453,8 +458,8 @@ static void enqueue(const int flags, const char *sender, const char *full_name,
rec_fprintf(dst, REC_TYPE_MESG, REC_TYPE_MESG_FORMAT, 0L);
skip_from_ = 1;
strip_cr = STRIP_CR_DUNNO;
- while ((type = rec_streamlf_get(VSTREAM_IN, buf, var_line_limit))
- != REC_TYPE_EOF) {
+ for (prev_type = 0; (type = rec_streamlf_get(VSTREAM_IN, buf, var_line_limit))
+ != REC_TYPE_EOF; prev_type = type) {
if (strip_cr == STRIP_CR_DUNNO && type == REC_TYPE_NORM) {
if (VSTRING_LEN(buf) > 0 && vstring_end(buf)[-1] == '\r')
strip_cr = STRIP_CR_DO;
@@ -472,7 +477,8 @@ static void enqueue(const int flags, const char *sender, const char *full_name,
if (strip_cr == STRIP_CR_DO && type == REC_TYPE_NORM)
if (VSTRING_LEN(buf) > 0 && vstring_end(buf)[-1] == '\r')
vstring_truncate(buf, VSTRING_LEN(buf) - 1);
- if ((flags & SM_FLAG_AEOF) && VSTRING_LEN(buf) == 1 && *STR(buf) == '.')
+ if ((flags & SM_FLAG_AEOF) && prev_type != REC_TYPE_CONT
+ && VSTRING_LEN(buf) == 1 && *STR(buf) == '.')
break;
if (REC_PUT_BUF(dst, type, buf) < 0)
msg_fatal_status(EX_TEMPFAIL,
diff --git a/gnu/dist/postfix/src/showq/Makefile.in b/gnu/dist/postfix/src/showq/Makefile.in
index 5c714ef1145..7b7b5cd366c 100644
--- a/gnu/dist/postfix/src/showq/Makefile.in
+++ b/gnu/dist/postfix/src/showq/Makefile.in
@@ -75,5 +75,8 @@ showq.o: ../../include/mail_scan_dir.h
showq.o: ../../include/mail_conf.h
showq.o: ../../include/record.h
showq.o: ../../include/rec_type.h
+showq.o: ../../include/quote_822_local.h
+showq.o: ../../include/quote_flags.h
+showq.o: ../../include/mail_addr.h
showq.o: ../../include/bounce_log.h
showq.o: ../../include/mail_server.h
diff --git a/gnu/dist/postfix/src/showq/showq.c b/gnu/dist/postfix/src/showq/showq.c
index 97147adeae8..8a59cbec6e8 100644
--- a/gnu/dist/postfix/src/showq/showq.c
+++ b/gnu/dist/postfix/src/showq/showq.c
@@ -80,6 +80,8 @@
#include <mail_conf.h>
#include <record.h>
#include <rec_type.h>
+#include <quote_822_local.h>
+#include <mail_addr.h>
#include <bounce_log.h>
/* Single-threaded server skeleton. */
@@ -89,6 +91,7 @@
/* Application-specific. */
int var_dup_filter_limit;
+char *var_empty_addr;
#define STRING_FORMAT "%-10s %8s %-20s %s\n"
#define DATA_FORMAT "%-10s%c%8ld %20.20s %s\n"
@@ -96,10 +99,15 @@ int var_dup_filter_limit;
static void showq_reasons(VSTREAM *, BOUNCE_LOG *, HTABLE *);
+#define STR(x) vstring_str(x)
+
+/* showq_report - report status of sender and recipients */
+
static void showq_report(VSTREAM *client, char *queue, char *id,
VSTREAM *qfile, long size)
{
VSTRING *buf = vstring_alloc(100);
+ VSTRING *printable_quoted_addr = vstring_alloc(100);
int rec_type;
time_t arrival_time = 0;
char *start;
@@ -109,6 +117,13 @@ static void showq_report(VSTREAM *client, char *queue, char *id,
char status = (strcmp(queue, MAIL_QUEUE_ACTIVE) == 0 ? '*' : ' ');
long offset;
+ /*
+ * XXX addresses in defer logfiles are in printable quoted form, while
+ * addresses in message envelope records are in raw unquoted form. This
+ * may change once we replace the present ad-hoc bounce/defer logfile
+ * format by one that is transparent for control etc. characters. See
+ * also: bounce/bounce_append_service.c.
+ */
while (!vstream_ferror(client) && (rec_type = rec_get(qfile, buf, 0)) > 0) {
start = vstring_str(buf);
switch (rec_type) {
@@ -121,18 +136,23 @@ static void showq_report(VSTREAM *client, char *queue, char *id,
break;
case REC_TYPE_FROM:
if (*start == 0)
- start = "(MAILER-DAEMON)";
+ start = var_empty_addr;
+ quote_822_local(printable_quoted_addr, start);
+ printable(STR(printable_quoted_addr), '?');
vstream_fprintf(client, DATA_FORMAT, id, status,
msg_size > 0 ? msg_size : size, arrival_time > 0 ?
asctime(localtime(&arrival_time)) : "??",
- printable(start, '?'));
+ STR(printable_quoted_addr));
break;
case REC_TYPE_RCPT:
if (*start == 0) /* can't happen? */
- start = "(MAILER-DAEMON)";
- if (dup_filter == 0 || htable_locate(dup_filter, start) == 0)
+ start = var_empty_addr;
+ quote_822_local(printable_quoted_addr, start);
+ printable(STR(printable_quoted_addr), '?');
+ if (dup_filter == 0
+ || htable_locate(dup_filter, STR(printable_quoted_addr)) == 0)
vstream_fprintf(client, STRING_FORMAT,
- "", "", "", printable(start, '?'));
+ "", "", "", STR(printable_quoted_addr));
break;
case REC_TYPE_MESG:
if ((offset = atol(start)) > 0
@@ -163,6 +183,7 @@ static void showq_report(VSTREAM *client, char *queue, char *id,
}
}
vstring_free(buf);
+ vstring_free(printable_quoted_addr);
if (dup_filter)
htable_free(dup_filter, (void (*) (char *)) 0);
}
@@ -307,8 +328,13 @@ int main(int argc, char **argv)
VAR_DUP_FILTER_LIMIT, DEF_DUP_FILTER_LIMIT, &var_dup_filter_limit, 0, 0,
0,
};
+ CONFIG_STR_TABLE str_table[] = {
+ VAR_EMPTY_ADDR, DEF_EMPTY_ADDR, &var_empty_addr, 1, 0,
+ 0,
+ };
single_server_main(argc, argv, showq_service,
MAIL_SERVER_INT_TABLE, int_table,
+ MAIL_SERVER_STR_TABLE, str_table,
0);
}
diff --git a/gnu/dist/postfix/src/smtp/Makefile.in b/gnu/dist/postfix/src/smtp/Makefile.in
index 035cd5acab4..0dc84f510e1 100644
--- a/gnu/dist/postfix/src/smtp/Makefile.in
+++ b/gnu/dist/postfix/src/smtp/Makefile.in
@@ -166,6 +166,7 @@ smtp_proto.o: ../../include/rec_type.h
smtp_proto.o: ../../include/off_cvt.h
smtp_proto.o: ../../include/mark_corrupt.h
smtp_proto.o: ../../include/quote_821_local.h
+smtp_proto.o: ../../include/quote_flags.h
smtp_proto.o: smtp.h
smtp_proto.o: ../../include/argv.h
smtp_proto.o: smtp_sasl.h
diff --git a/gnu/dist/postfix/src/smtp/smtp.c b/gnu/dist/postfix/src/smtp/smtp.c
index 9c61d89dbba..399ea676622 100644
--- a/gnu/dist/postfix/src/smtp/smtp.c
+++ b/gnu/dist/postfix/src/smtp/smtp.c
@@ -97,8 +97,8 @@
/* Never send EHLO at the start of a connection.
/* .IP \fBsmtp_bind_address\fR
/* Numerical source network address to bind to when making a connection.
-/* .IP \fBsmtp_break_lines\fR
-/* Break lines > \fB$line_length_limit\fR into multiple shorter lines.
+/* .IP \fBsmtp_line_length_limit\fR
+/* Length limit for SMTP message content lines. Zero means no limit.
/* Some SMTP servers misbehave on long lines.
/* .IP \fBsmtp_skip_4xx_greeting\fR
/* Skip servers that greet us with a 4xx status code.
@@ -113,7 +113,7 @@
/* The time a message must be queued before the CISCO PIX firewall
/* <CR><LF>.<CR><LF> bug workaround is turned on.
/* .SH "Authentication controls"
-/* .IP \fBsmtp_enable_sasl_auth\fR
+/* .IP \fBsmtp_sasl_auth_enable\fR
/* Enable per-session authentication as per RFC 2554 (SASL).
/* By default, Postfix is built without SASL support.
/* .IP \fBsmtp_sasl_password_maps\fR
@@ -259,9 +259,9 @@ char *var_smtp_sasl_passwd;
bool var_smtp_sasl_enable;
char *var_smtp_bind_addr;
bool var_smtp_rand_addr;
-bool var_smtp_break_lines;
int var_smtp_pix_thresh;
int var_smtp_pix_delay;
+int var_smtp_line_limit;
/*
* Global variables. smtp_errno is set by the address lookup routines and by
@@ -429,6 +429,7 @@ int main(int argc, char **argv)
0,
};
static CONFIG_INT_TABLE int_table[] = {
+ VAR_SMTP_LINE_LIMIT, DEF_SMTP_LINE_LIMIT, &var_smtp_line_limit, 0, 0,
0,
};
static CONFIG_BOOL_TABLE bool_table[] = {
@@ -440,7 +441,6 @@ int main(int argc, char **argv)
VAR_SMTP_NEVER_EHLO, DEF_SMTP_NEVER_EHLO, &var_smtp_never_ehlo,
VAR_SMTP_SASL_ENABLE, DEF_SMTP_SASL_ENABLE, &var_smtp_sasl_enable,
VAR_SMTP_RAND_ADDR, DEF_SMTP_RAND_ADDR, &var_smtp_rand_addr,
- VAR_SMTP_BREAK_LINES, DEF_SMTP_BREAK_LINES, &var_smtp_break_lines,
0,
};
diff --git a/gnu/dist/postfix/src/smtp/smtp_proto.c b/gnu/dist/postfix/src/smtp/smtp_proto.c
index 04e0db3fcde..0b55de656b3 100644
--- a/gnu/dist/postfix/src/smtp/smtp_proto.c
+++ b/gnu/dist/postfix/src/smtp/smtp_proto.c
@@ -296,16 +296,27 @@ int smtp_xfer(SMTP_STATE *state)
int sndbuffree;
SOCKOPT_SIZE optlen = sizeof(sndbufsize);
int mail_from_rejected;
+ int space_left = var_smtp_line_limit;
+ int data_left;
+ char *data_start;
/*
* Macros for readability.
*/
-#define REWRITE_ADDRESS(addr) do { \
- if (*(addr)) { \
- quote_821_local(state->scratch, addr); \
- smtp_unalias_addr(state->scratch2, vstring_str(state->scratch)); \
- myfree(addr); \
- addr = mystrdup(vstring_str(state->scratch2)); \
+#define REWRITE_ADDRESS(dst, mid, src) do { \
+ if (*(src)) { \
+ quote_821_local(mid, src); \
+ smtp_unalias_addr(dst, vstring_str(mid)); \
+ } else { \
+ vstring_strcpy(dst, src); \
+ } \
+ } while (0)
+
+#define QUOTE_ADDRESS(dst, src) do { \
+ if (*(src)) { \
+ quote_821_local(dst, src); \
+ } else { \
+ vstring_strcpy(dst, src); \
} \
} while (0)
@@ -396,11 +407,15 @@ int smtp_xfer(SMTP_STATE *state)
* Build the MAIL FROM command.
*/
case SMTP_STATE_MAIL:
- if (*request->sender)
- if (var_disable_dns == 0)
- REWRITE_ADDRESS(request->sender);
- vstring_sprintf(next_command, "MAIL FROM:<%s>", request->sender);
- if (state->features & SMTP_FEATURE_SIZE)
+ if (var_disable_dns == 0) {
+ REWRITE_ADDRESS(state->scratch, state->scratch2,
+ request->sender);
+ } else {
+ QUOTE_ADDRESS(state->scratch, request->sender);
+ }
+ vstring_sprintf(next_command, "MAIL FROM:<%s>",
+ vstring_str(state->scratch));
+ if (state->features & SMTP_FEATURE_SIZE) /* RFC 1652 */
vstring_sprintf_append(next_command, " SIZE=%lu",
request->data_size);
next_state = SMTP_STATE_RCPT;
@@ -412,9 +427,14 @@ int smtp_xfer(SMTP_STATE *state)
*/
case SMTP_STATE_RCPT:
rcpt = request->rcpt_list.info + send_rcpt;
- if (var_disable_dns == 0)
- REWRITE_ADDRESS(rcpt->address);
- vstring_sprintf(next_command, "RCPT TO:<%s>", rcpt->address);
+ if (var_disable_dns == 0) {
+ REWRITE_ADDRESS(state->scratch, state->scratch2,
+ rcpt->address);
+ } else {
+ QUOTE_ADDRESS(state->scratch, rcpt->address);
+ }
+ vstring_sprintf(next_command, "RCPT TO:<%s>",
+ vstring_str(state->scratch));
if ((next_rcpt = send_rcpt + 1) == request->rcpt_list.len)
next_state = SMTP_STATE_DATA;
break;
@@ -665,16 +685,38 @@ int smtp_xfer(SMTP_STATE *state)
if (prev_type != REC_TYPE_CONT)
if (vstring_str(state->scratch)[0] == '.')
smtp_fputc('.', session->stream);
- if (var_smtp_break_lines)
- rec_type = REC_TYPE_NORM;
- if (rec_type == REC_TYPE_CONT)
- smtp_fwrite(vstring_str(state->scratch),
- VSTRING_LEN(state->scratch),
- session->stream);
- else
- smtp_fputs(vstring_str(state->scratch),
- VSTRING_LEN(state->scratch),
- session->stream);
+
+ /*
+ * Deal with an impedance mismatch between Postfix queue
+ * files (record length <= $message_line_length_limit) and
+ * SMTP (DATA record length <= $smtp_line_length_limit). The
+ * code below does a little too much work when the SMTP line
+ * length limit is disabled, but it avoids code duplication,
+ * and thus, it avoids testing and maintenance problems.
+ */
+ data_left = VSTRING_LEN(state->scratch);
+ data_start = vstring_str(state->scratch);
+ do {
+ if (var_smtp_line_limit > 0 && data_left >= space_left) {
+ smtp_fputs(data_start, space_left, session->stream);
+ data_start += space_left;
+ data_left -= space_left;
+ space_left = var_smtp_line_limit;
+ if (data_left > 0 || rec_type == REC_TYPE_CONT) {
+ smtp_fputc(' ', session->stream);
+ space_left -= 1;
+ }
+ } else {
+ if (rec_type == REC_TYPE_CONT) {
+ smtp_fwrite(data_start, data_left, session->stream);
+ space_left -= data_left;
+ } else {
+ smtp_fputs(data_start, data_left, session->stream);
+ space_left = var_smtp_line_limit;
+ }
+ break;
+ }
+ } while (data_left > 0);
prev_type = rec_type;
}
diff --git a/gnu/dist/postfix/src/trivial-rewrite/Makefile.in b/gnu/dist/postfix/src/trivial-rewrite/Makefile.in
index 7f33c4c376f..1ee66fde9a6 100644
--- a/gnu/dist/postfix/src/trivial-rewrite/Makefile.in
+++ b/gnu/dist/postfix/src/trivial-rewrite/Makefile.in
@@ -76,6 +76,7 @@ resolve.o: ../../include/rewrite_clnt.h
resolve.o: ../../include/resolve_local.h
resolve.o: ../../include/mail_conf.h
resolve.o: ../../include/quote_822_local.h
+resolve.o: ../../include/quote_flags.h
resolve.o: ../../include/tok822.h
resolve.o: ../../include/resolve_clnt.h
resolve.o: trivial-rewrite.h
diff --git a/gnu/dist/postfix/src/trivial-rewrite/resolve.c b/gnu/dist/postfix/src/trivial-rewrite/resolve.c
index ba446301934..d9f2aab054a 100644
--- a/gnu/dist/postfix/src/trivial-rewrite/resolve.c
+++ b/gnu/dist/postfix/src/trivial-rewrite/resolve.c
@@ -97,9 +97,17 @@ void resolve_addr(char *addr, VSTRING *channel, VSTRING *nexthop,
/*
* The address is in internalized (unquoted) form, so we must externalize
* it first before we can parse it.
+ *
+ * But practically, we have to look at the unquoted form so that routing
+ * characters like @ remain visible, in order to stop user@domain@domain
+ * relay attempts when forwarding mail to a primary Sendmail MX host.
*/
- quote_822_local(addr_buf, addr);
- tree = tok822_scan_addr(vstring_str(addr_buf));
+ if (var_resolve_dequoted) {
+ tree = tok822_scan_addr(addr);
+ } else {
+ quote_822_local(addr_buf, addr);
+ tree = tok822_scan_addr(vstring_str(addr_buf));
+ }
/*
* Preliminary resolver: strip off all instances of the local domain.
diff --git a/gnu/dist/postfix/src/trivial-rewrite/rewrite.c b/gnu/dist/postfix/src/trivial-rewrite/rewrite.c
index e1ae59cf751..9ff6a12f092 100644
--- a/gnu/dist/postfix/src/trivial-rewrite/rewrite.c
+++ b/gnu/dist/postfix/src/trivial-rewrite/rewrite.c
@@ -118,7 +118,8 @@ void rewrite_tree(char *unused_ruleset, TOK822 *tree)
* Strip source route.
*/
if (tree->head->type == '@'
- && (colon = tok822_find_type(tree->head, ':')) != 0)
+ && (colon = tok822_find_type(tree->head, ':')) != 0
+ && colon != tree->tail)
tok822_free_tree(tok822_sub_keep_after(tree, colon));
/*
diff --git a/gnu/dist/postfix/src/trivial-rewrite/trivial-rewrite.c b/gnu/dist/postfix/src/trivial-rewrite/trivial-rewrite.c
index 71dc8b2f1dd..9e0e0b8c8be 100644
--- a/gnu/dist/postfix/src/trivial-rewrite/trivial-rewrite.c
+++ b/gnu/dist/postfix/src/trivial-rewrite/trivial-rewrite.c
@@ -64,6 +64,12 @@
/* List of domains that this machine considers local.
/* .IP \fBmyorigin\fR
/* The domain that locally-posted mail appears to come from.
+/* .IP \fBresolve_unquoted_address\fR
+/* When resolving an address, do not quote the address localpart as
+/* per RFC 822, so that additional \fB@\fR, \fB%\fR or \fB!\fR
+/* characters remain visible. This is technically incorrect, but
+/* allows us to stop relay attacks when forwarding mail to a Sendmail
+/* primary MX host.
/* .SH Rewriting
/* .ad
/* .fi
@@ -93,9 +99,9 @@
/* Syntax is \fItransport\fR:\fInexthop\fR; see \fBtransport\fR(5)
/* for details. The :\fInexthop\fR part is optional.
/* .IP \fBparent_domain_matches_subdomains\fR
-/* List of Postfix features that use \fIdomain.name\fR patterns
-/* to match \fIsub.domain.name\fR (as opposed to
-/* requiring \fI.domain.name\fR patterns).
+/* List of Postfix features that use \fIdomain.tld\fR patterns
+/* to match \fIsub.domain.tld\fR (as opposed to
+/* requiring \fI.domain.tld\fR patterns).
/* .IP \fBrelayhost\fR
/* The default host to send non-local mail to when no entry is matched
/* in the \fBtransport\fR(5) table.
@@ -167,6 +173,7 @@ bool var_append_dot_mydomain;
bool var_append_at_myorigin;
bool var_percent_hack;
char *var_local_transport;
+int var_resolve_dequoted;
/* rewrite_service - read request and send reply */
@@ -234,6 +241,7 @@ int main(int argc, char **argv)
VAR_APP_DOT_MYDOMAIN, DEF_APP_DOT_MYDOMAIN, &var_append_dot_mydomain,
VAR_APP_AT_MYORIGIN, DEF_APP_AT_MYORIGIN, &var_append_at_myorigin,
VAR_PERCENT_HACK, DEF_PERCENT_HACK, &var_percent_hack,
+ VAR_RESOLVE_DEQUOTED, DEF_RESOLVE_DEQUOTED, &var_resolve_dequoted,
0,
};
diff --git a/gnu/dist/postfix/src/util/dict.c b/gnu/dist/postfix/src/util/dict.c
index 5fd30887983..92fedc57e1c 100644
--- a/gnu/dist/postfix/src/util/dict.c
+++ b/gnu/dist/postfix/src/util/dict.c
@@ -508,11 +508,11 @@ int dict_changed(void)
ht_info_list = htable_list(dict_table);
for (status = 0, ht = ht_info_list; status == 0 && (h = *ht) != 0; ht++) {
dict = ((DICT_NODE *) h->value)->dict;
- if (dict->fd < 0) /* not file-based */
+ if (dict->stat_fd < 0) /* not file-based */
continue;
if (dict->mtime == 0) /* not bloody likely */
msg_warn("%s: table %s: null time stamp", myname, h->key);
- if (fstat(dict->fd, &st) < 0)
+ if (fstat(dict->stat_fd, &st) < 0)
msg_fatal("%s: fstat: %m", myname);
status = (st.st_mtime != dict->mtime || st.st_nlink == 0);
}
diff --git a/gnu/dist/postfix/src/util/dict.h b/gnu/dist/postfix/src/util/dict.h
index 1d9d8c4a129..9cad9f0e475 100644
--- a/gnu/dist/postfix/src/util/dict.h
+++ b/gnu/dist/postfix/src/util/dict.h
@@ -35,7 +35,8 @@ typedef struct DICT {
int (*delete) (struct DICT *, const char *);
int (*sequence) (struct DICT *, int, const char **, const char **);
void (*close) (struct DICT *);
- int fd; /* for dict_update() lock */
+ int lock_fd; /* for dict_update() lock */
+ int stat_fd; /* change detection */
time_t mtime; /* mod time at open */
} DICT;
diff --git a/gnu/dist/postfix/src/util/dict_alloc.c b/gnu/dist/postfix/src/util/dict_alloc.c
index 005e47aefb6..6ea4980c175 100644
--- a/gnu/dist/postfix/src/util/dict_alloc.c
+++ b/gnu/dist/postfix/src/util/dict_alloc.c
@@ -116,7 +116,8 @@ DICT *dict_alloc(const char *dict_type, const char *dict_name, int size)
dict->delete = dict_default_delete;
dict->sequence = dict_default_sequence;
dict->close = dict_default_close;
- dict->fd = -1;
+ dict->lock_fd = -1;
+ dict->stat_fd = -1;
dict->mtime = 0;
return dict;
}
diff --git a/gnu/dist/postfix/src/util/dict_db.c b/gnu/dist/postfix/src/util/dict_db.c
index 423244a3a7f..9eeb3a780bc 100644
--- a/gnu/dist/postfix/src/util/dict_db.c
+++ b/gnu/dist/postfix/src/util/dict_db.c
@@ -158,7 +158,7 @@ static const char *dict_db_lookup(DICT *dict, const char *name)
* Acquire a shared lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
- && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
+ && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
msg_fatal("%s: lock dictionary: %m", dict_db->dict.name);
/*
@@ -198,7 +198,7 @@ static const char *dict_db_lookup(DICT *dict, const char *name)
* Release the shared lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
- && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
+ && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
msg_fatal("%s: unlock dictionary: %m", dict_db->dict.name);
return (result);
@@ -246,7 +246,7 @@ static void dict_db_update(DICT *dict, const char *name, const char *value)
* Acquire an exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
- && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
+ && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
msg_fatal("%s: lock dictionary: %m", dict_db->dict.name);
/*
@@ -271,7 +271,7 @@ static void dict_db_update(DICT *dict, const char *name, const char *value)
* Release the exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
- && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
+ && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
msg_fatal("%s: unlock dictionary: %m", dict_db->dict.name);
}
@@ -289,7 +289,7 @@ static int dict_db_delete(DICT *dict, const char *name)
* Acquire an exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
- && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
+ && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
msg_fatal("%s: lock dictionary: %m", dict_db->dict.name);
/*
@@ -325,7 +325,7 @@ static int dict_db_delete(DICT *dict, const char *name)
* Release the exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
- && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
+ && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
msg_fatal("%s: unlock dictionary: %m", dict_db->dict.name);
return status;
@@ -367,7 +367,7 @@ static int dict_db_sequence(DICT *dict, const int function,
* Acquire an exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
- && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
+ && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
msg_fatal("%s: lock dictionary: %m", dict_db->dict.name);
if ((status = db->seq(db, &db_key, &db_value, db_function)) < 0)
@@ -377,7 +377,7 @@ static int dict_db_sequence(DICT *dict, const int function,
* Release the exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
- && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
+ && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
msg_fatal("%s: unlock dictionary: %m", dict_db->dict.name);
if (status == 0) {
@@ -537,8 +537,9 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
dict_db->dict.delete = dict_db_delete;
dict_db->dict.sequence = dict_db_sequence;
dict_db->dict.close = dict_db_close;
- dict_db->dict.fd = dbfd;
- if (fstat(dict_db->dict.fd, &st) < 0)
+ dict_db->dict.lock_fd = dbfd;
+ dict_db->dict.stat_fd = dbfd;
+ if (fstat(dict_db->dict.stat_fd, &st) < 0)
msg_fatal("dict_db_open: fstat: %m");
dict_db->dict.mtime = st.st_mtime;
@@ -552,7 +553,8 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
&& 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);
+ close_on_exec(dict_db->dict.lock_fd, CLOSE_ON_EXEC);
+ close_on_exec(dict_db->dict.stat_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);
diff --git a/gnu/dist/postfix/src/util/dict_dbm.c b/gnu/dist/postfix/src/util/dict_dbm.c
index 575d5eb54c9..8949a8cbffc 100644
--- a/gnu/dist/postfix/src/util/dict_dbm.c
+++ b/gnu/dist/postfix/src/util/dict_dbm.c
@@ -84,7 +84,7 @@ static const char *dict_dbm_lookup(DICT *dict, const char *name)
* Acquire an exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
- && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
+ && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
msg_fatal("%s: lock dictionary: %m", dict_dbm->dict.name);
/*
@@ -122,7 +122,7 @@ static const char *dict_dbm_lookup(DICT *dict, const char *name)
* Release the exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
- && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
+ && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
msg_fatal("%s: unlock dictionary: %m", dict_dbm->dict.name);
return (result);
@@ -167,7 +167,7 @@ static void dict_dbm_update(DICT *dict, const char *name, const char *value)
* Acquire an exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
- && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
+ && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
msg_fatal("%s: lock dictionary: %m", dict_dbm->dict.name);
/*
@@ -189,7 +189,7 @@ static void dict_dbm_update(DICT *dict, const char *name, const char *value)
* Release the exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
- && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
+ && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
msg_fatal("%s: unlock dictionary: %m", dict_dbm->dict.name);
}
@@ -206,7 +206,7 @@ static int dict_dbm_delete(DICT *dict, const char *name)
* Acquire an exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
- && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
+ && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
msg_fatal("%s: lock dictionary: %m", dict_dbm->dict.name);
/*
@@ -247,7 +247,7 @@ static int dict_dbm_delete(DICT *dict, const char *name)
* Release the exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
- && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
+ && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
msg_fatal("%s: unlock dictionary: %m", dict_dbm->dict.name);
return (status);
@@ -270,7 +270,7 @@ static int dict_dbm_sequence(DICT *dict, const int function,
* Acquire an exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
- && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
+ && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
msg_fatal("%s: lock dictionary: %m", dict_dbm->dict.name);
/*
@@ -291,7 +291,7 @@ static int dict_dbm_sequence(DICT *dict, const int function,
* Release the exclusive lock.
*/
if ((dict->flags & DICT_FLAG_LOCK)
- && myflock(dict->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
+ && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
msg_fatal("%s: unlock dictionary: %m", dict_dbm->dict.name);
if (dbm_key.dptr != 0 && dbm_key.dsize > 0) {
@@ -379,7 +379,7 @@ DICT *dict_dbm_open(const char *path, int open_flags, int dict_flags)
* time domain) locks while rewriting the entire file.
*/
if (dict_flags & DICT_FLAG_LOCK) {
- dbm_path = concatenate(path, ".pag", (char *) 0);
+ dbm_path = concatenate(path, ".dir", (char *) 0);
if ((lock_fd = open(dbm_path, open_flags, 0644)) < 0)
msg_fatal("open database %s: %m", dbm_path);
if (myflock(lock_fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
@@ -404,8 +404,11 @@ DICT *dict_dbm_open(const char *path, int open_flags, int dict_flags)
dict_dbm->dict.delete = dict_dbm_delete;
dict_dbm->dict.sequence = dict_dbm_sequence;
dict_dbm->dict.close = dict_dbm_close;
- dict_dbm->dict.fd = dbm_pagfno(dbm);
- if (fstat(dict_dbm->dict.fd, &st) < 0)
+ dict_dbm->dict.lock_fd = dbm_dirfno(dbm);
+ dict_dbm->dict.stat_fd = dbm_pagfno(dbm);
+ if (dict_dbm->dict.lock_fd == dict_dbm->dict.stat_fd)
+ msg_fatal("open database %s: cannot support GDBM", path);
+ if (fstat(dict_dbm->dict.stat_fd, &st) < 0)
msg_fatal("dict_dbm_open: fstat: %m");
dict_dbm->dict.mtime = st.st_mtime;
diff --git a/gnu/dist/postfix/src/util/dict_ldap.c b/gnu/dist/postfix/src/util/dict_ldap.c
index 2cf8936c43e..a3b4d0cae1d 100644
--- a/gnu/dist/postfix/src/util/dict_ldap.c
+++ b/gnu/dist/postfix/src/util/dict_ldap.c
@@ -586,7 +586,7 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
*/
if (*(sub) == '%') {
char *u = vstring_str(escaped_name);
- char *p = strchr(u, '@');
+ char *p = strrchr(u, '@');
switch (*(sub + 1)) {
case 'd':
diff --git a/gnu/dist/postfix/src/util/strcasecmp.c b/gnu/dist/postfix/src/util/strcasecmp.c
new file mode 100644
index 00000000000..6ed4671349c
--- /dev/null
+++ b/gnu/dist/postfix/src/util/strcasecmp.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcasecmp.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys_defs.h>
+#include <ctype.h>
+
+int strcasecmp(const char *s1, const char *s2)
+{
+ const unsigned char *us1 = (const unsigned char *) s1;
+ const unsigned char *us2 = (const unsigned char *) s2;
+
+ while (TOLOWER(*us1) == TOLOWER(*us2++))
+ if (*us1++ == '\0')
+ return (0);
+ return (TOLOWER(*us1) - TOLOWER(*--us2));
+}
+
+int strncasecmp(const char *s1, const char *s2, size_t n)
+{
+ if (n != 0) {
+ const unsigned char *us1 = (const unsigned char *) s1;
+ const unsigned char *us2 = (const unsigned char *) s2;
+
+ do {
+ if (TOLOWER(*us1) != TOLOWER(*us2++))
+ return (TOLOWER(*us1) - TOLOWER(*--us2));
+ if (*us1++ == '\0')
+ break;
+ } while (--n != 0);
+ }
+ return (0);
+}