diff options
| author | itojun <itojun@NetBSD.org> | 2002-06-08 22:37:07 +0000 |
|---|---|---|
| committer | itojun <itojun@NetBSD.org> | 2002-06-08 22:37:07 +0000 |
| commit | 4a4a5f078294ab7d6c2c8926db43159e7673daec (patch) | |
| tree | 941afff1dcb247fc805a2b2382bda1381f5c7720 /gnu | |
| parent | d7d4214831e4287ca9b8b1dfaad1f40080d1f4b0 (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.in | 1 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/qmqpd/qmqpd.c | 2 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/sendmail/sendmail.c | 12 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/showq/Makefile.in | 3 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/showq/showq.c | 36 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/smtp/Makefile.in | 1 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/smtp/smtp.c | 10 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/smtp/smtp_proto.c | 90 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/trivial-rewrite/Makefile.in | 1 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/trivial-rewrite/resolve.c | 12 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/trivial-rewrite/rewrite.c | 3 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/trivial-rewrite/trivial-rewrite.c | 14 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/util/dict.c | 4 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/util/dict.h | 3 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/util/dict_alloc.c | 3 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/util/dict_db.c | 24 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/util/dict_dbm.c | 25 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/util/dict_ldap.c | 2 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/util/strcasecmp.c | 66 |
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); +} |
