From: Wietse Venema Date: Wed, 14 Nov 2001 05:00:00 +0000 (-0500) Subject: snapshot-20011114 X-Git-Tag: v1.1.0~30 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=456a68b122acc8cbdc173a9a2439e38d0c80b660;p=thirdparty%2Fpostfix.git snapshot-20011114 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 686e1d18d..1880fc285 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -5576,17 +5576,10 @@ Apologies for any names omitted. Bugfix: missing terminator in new attribute-based function call caused signal 11. File: src/cleanup/cleanup.c. - Lame workaround for ESTALE errors with mail deliver over - NFS. Some bandages have been added to the local delivery - agent. Wietse maintains that Postfix offers no guarantee - for reliable delivery over NFS. +20011114 -20011107 - - Workaround: in order to get mail past PIX firewall bugs, - Postfix now waits until the socket send buffer is empty - before sending the final ".". Files: - util/sock_empty_wait.c, smtp/smtp_proto.c. + Bugfix: reset the smtpd command transaction log between + deliveries. File: smtpd/smtpd.c. Open problems: @@ -5599,8 +5592,6 @@ Open problems: Medium: smtpd access maps don't understand the recipient delimiter setting. - Low: default domain for appending to unqualified recipients. - Low: The $process_id_directory setting is not used anywhere in Postfix. Problem reported by Michael Smith, texas.net. This should be documented, or better, the code should warn diff --git a/postfix/INSTALL b/postfix/INSTALL index 8c5419b22..3d6748521 100644 --- a/postfix/INSTALL +++ b/postfix/INSTALL @@ -213,8 +213,8 @@ In order to install or upgrade Postfix: - Run the INSTALL.sh script as the super-user: - # make install (interactive version, first time install) - # make upgrade (non-interactive version, for upgrades) + # make install (interactive version, first time install) + # make install #include #include -#include /* Global library. */ @@ -179,11 +178,8 @@ int smtp_helo(SMTP_STATE *state) * does not span a packet boundary. This hurts performance so it is not * on by default. */ - if (resp->str[strspn(resp->str, "20 *\t\n")] == 0) { - msg_info("enabling PIX . workaround for %s", - session->namaddr); + if (resp->str[strspn(resp->str, "20 *\t\n")] == 0) state->features |= SMTP_FEATURE_MAYBEPIX; - } /* * See if we are talking to ourself. This should not be possible with the @@ -200,9 +196,9 @@ int smtp_helo(SMTP_STATE *state) } else if (strcasecmp(word, "ESMTP") == 0) state->features |= SMTP_FEATURE_ESMTP; } - if (var_smtp_always_ehlo && (state->features & SMTP_FEATURE_MAYBEPIX) == 0) + if (var_smtp_always_ehlo) state->features |= SMTP_FEATURE_ESMTP; - if (var_smtp_never_ehlo || (state->features & SMTP_FEATURE_MAYBEPIX) != 0) + if (var_smtp_never_ehlo) state->features &= ~SMTP_FEATURE_ESMTP; /* @@ -661,11 +657,9 @@ int smtp_xfer(SMTP_STATE *state) if (prev_type == REC_TYPE_CONT) /* missing newline at end */ smtp_fputs("", 0, session->stream); - if ((state->features & SMTP_FEATURE_MAYBEPIX) != 0) { + if ((state->features & SMTP_FEATURE_ESMTP) == 0 + && (state->features & SMTP_FEATURE_MAYBEPIX) != 0) vstream_fflush(session->stream);/* hurts performance */ - sock_empty_wait(vstream_fileno(session->stream), - session->stream->timeout / 2); - } if (vstream_ferror(state->src)) msg_fatal("queue file read error"); if (rec_type != REC_TYPE_XTRA) diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index f3954d1b0..7bb85f3bc 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -1059,6 +1059,18 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) */ state->where = SMTPD_AFTER_DOT; + /* + * Notify the postmaster if there were errors. This usually indicates a + * client configuration problem, or that someone is trying nasty things. + * Either is significant enough to bother the postmaster. XXX Can't + * report problems when running in stand-alone mode: postmaster notices + * require availability of the cleanup service. + */ + if (state->history != 0 && state->client != VSTREAM_IN + && (state->error_mask & state->notify_mask)) + smtpd_chat_notify(state); + smtpd_chat_reset(state); + /* * Cleanup. The client may send another MAIL command. */ diff --git a/postfix/src/smtpd/smtpd.h b/postfix/src/smtpd/smtpd.h index 20386ad73..29fb3d2d7 100644 --- a/postfix/src/smtpd/smtpd.h +++ b/postfix/src/smtpd/smtpd.h @@ -76,7 +76,6 @@ typedef struct SMTPD_STATE { VSTRING *sasl_encoded; VSTRING *sasl_decoded; #endif - int warn_if_reject; } SMTPD_STATE; extern void smtpd_state_init(SMTPD_STATE *, VSTREAM *); diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c index fde64186a..d558c37c3 100644 --- a/postfix/src/smtpd/smtpd_check.c +++ b/postfix/src/smtpd/smtpd_check.c @@ -585,20 +585,6 @@ static int smtpd_check_reject(SMTPD_STATE *state, int error_class, char *format,...) { va_list ap; - int warn_if_reject; - const char *whatsup; - - /* - * Do not reject mail if we were asked to warn only. However, - * configuration errors cannot be converted into warnings. - */ - if (state->warn_if_reject && error_class != MAIL_ERROR_SOFTWARE) { - warn_if_reject = 1; - whatsup = "reject_warning"; - } else { - warn_if_reject = 0; - whatsup = "reject"; - } /* * Update the error class mask, and format the response. XXX What about @@ -648,22 +634,22 @@ static int smtpd_check_reject(SMTPD_STATE *state, int error_class, * rejected. Print the request, client name/address, and response. */ if (state->recipient && state->sender) { - msg_info("%s: %s from %s: %s; from=<%s> to=<%s>", - whatsup, state->where, state->namaddr, STR(error_text), + msg_info("reject: %s from %s: %s; from=<%s> to=<%s>", + state->where, state->namaddr, STR(error_text), state->sender, state->recipient); } else if (state->recipient) { - msg_info("%s: %s from %s: %s; to=<%s>", - whatsup, state->where, state->namaddr, STR(error_text), + msg_info("reject: %s from %s: %s; to=<%s>", + state->where, state->namaddr, STR(error_text), state->recipient); } else if (state->sender) { - msg_info("%s: %s from %s: %s; from=<%s>", - whatsup, state->where, state->namaddr, STR(error_text), + msg_info("reject: %s from %s: %s; from=<%s>", + state->where, state->namaddr, STR(error_text), state->sender); } else { - msg_info("%s: %s from %s: %s", - whatsup, state->where, state->namaddr, STR(error_text)); + msg_info("reject: %s from %s: %s", + state->where, state->namaddr, STR(error_text)); } - return (warn_if_reject ? 0 : SMTPD_CHECK_REJECT); + return (SMTPD_CHECK_REJECT); } /* reject_dict_retry - reject with temporary failure if dict lookup fails */ @@ -1838,7 +1824,6 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, int status = 0; ARGV *list; int found; - int saved_recursion = state->recursion; if (msg_verbose) msg_info("%s: START", myname); @@ -1848,15 +1833,6 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, if (msg_verbose) msg_info("%s: name=%s", myname, name); - /* - * Pseudo restrictions. - */ - if (strcasecmp(name, WARN_IF_REJECT) == 0) { - if (state->warn_if_reject == 0) - state->warn_if_reject = state->recursion; - continue; - } - /* * Spoof the is_map_command() routine, so that we do not have to make * special cases for the implicit short-hand access map notation. @@ -1871,14 +1847,14 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, */ if (strcasecmp(name, PERMIT_ALL) == 0) { status = SMTPD_CHECK_OK; - if (cpp[1] != 0 && state->warn_if_reject == 0) + if (cpp[1] != 0) msg_warn("restriction `%s' after `%s' is ignored", cpp[1], PERMIT_ALL); } else if (strcasecmp(name, REJECT_ALL) == 0) { status = smtpd_check_reject(state, MAIL_ERROR_POLICY, "%d <%s>: %s rejected: Access denied", var_reject_code, reply_name, reply_class); - if (cpp[1] != 0 && state->warn_if_reject == 0) + if (cpp[1] != 0) msg_warn("restriction `%s' after `%s' is ignored", cpp[1], REJECT_ALL); } else if (strcasecmp(name, REJECT_UNAUTH_PIPE) == 0) { @@ -1987,7 +1963,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, if (state->recipient) status = check_relay_domains(state, state->recipient, state->recipient, SMTPD_NAME_RECIPIENT); - if (cpp[1] != 0 && state->warn_if_reject == 0) + if (cpp[1] != 0) msg_warn("restriction `%s' after `%s' is ignored", cpp[1], CHECK_RELAY_DOMAINS); #ifdef USE_SASL_AUTH @@ -2035,17 +2011,12 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, if (msg_verbose) msg_info("%s: name=%s status=%d", myname, name, status); - if (state->warn_if_reject >= state->recursion) - state->warn_if_reject = 0; - if (status != 0) break; } if (msg_verbose && name == 0) msg_info("%s: END", myname); - state->recursion = saved_recursion; - return (status); } @@ -2064,7 +2035,7 @@ char *smtpd_check_client(SMTPD_STATE *state) /* * Apply restrictions in the order as specified. */ - state->recursion = 1; + state->recursion = 0; status = setjmp(smtpd_check_buf); if (status == 0 && client_restrctions->argc) status = generic_checks(state, client_restrctions, state->namaddr, @@ -2110,7 +2081,7 @@ char *smtpd_check_helo(SMTPD_STATE *state, char *helohost) /* * Apply restrictions in the order as specified. */ - state->recursion = 1; + state->recursion = 0; status = setjmp(smtpd_check_buf); if (status == 0 && helo_restrctions->argc) status = generic_checks(state, helo_restrctions, state->helo_name, @@ -2146,7 +2117,7 @@ char *smtpd_check_mail(SMTPD_STATE *state, char *sender) /* * Apply restrictions in the order as specified. */ - state->recursion = 1; + state->recursion = 0; status = setjmp(smtpd_check_buf); if (status == 0 && mail_restrctions->argc) status = generic_checks(state, mail_restrctions, sender, @@ -2200,7 +2171,7 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient) /* * Apply restrictions in the order as specified. */ - state->recursion = 1; + state->recursion = 0; status = setjmp(smtpd_check_buf); if (status == 0 && rcpt_restrctions->argc) status = generic_checks(state, rcpt_restrctions, @@ -2245,7 +2216,7 @@ char *smtpd_check_etrn(SMTPD_STATE *state, char *domain) /* * Apply restrictions in the order as specified. */ - state->recursion = 1; + state->recursion = 0; status = setjmp(smtpd_check_buf); if (status == 0 && etrn_restrctions->argc) status = generic_checks(state, etrn_restrctions, domain, diff --git a/postfix/src/smtpd/smtpd_state.c b/postfix/src/smtpd/smtpd_state.c index 6e7236543..ca4929634 100644 --- a/postfix/src/smtpd/smtpd_state.c +++ b/postfix/src/smtpd/smtpd_state.c @@ -91,7 +91,6 @@ void smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream) state->recursion = 0; state->msg_size = 0; state->junk_cmds = 0; - state->warn_if_reject = 0; #ifdef USE_SASL_AUTH if (SMTPD_STAND_ALONE(state)) diff --git a/postfix/src/util/Makefile.in b/postfix/src/util/Makefile.in index 95ba1e335..b31dc93aa 100644 --- a/postfix/src/util/Makefile.in +++ b/postfix/src/util/Makefile.in @@ -24,7 +24,7 @@ SRCS = argv.c argv_split.c basename.c binhash.c chroot_uid.c \ sane_link.c unescape.c timed_read.c timed_write.c dict_tcp.c \ hex_quote.c dict_alloc.c rand_sleep.c sane_time.c dict_debug.c \ sane_socketpair.c myrand.c netstring.c ctable.c attr_print.c intv.c \ - attr_scan.c base64_code.c sock_empty_wait.c attr_print0.c attr_scan0.c + attr_scan.c base64_code.c OBJS = argv.o argv_split.o basename.o binhash.o chroot_uid.o \ close_on_exec.o concatenate.o dict.o dict_db.o dict_dbm.o \ dict_env.o dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \ @@ -50,7 +50,7 @@ OBJS = argv.o argv_split.o basename.o binhash.o chroot_uid.o \ sane_link.o unescape.o timed_read.o timed_write.o dict_tcp.o \ hex_quote.o dict_alloc.o rand_sleep.o sane_time.o dict_debug.o \ sane_socketpair.o myrand.o netstring.o ctable.o attr_print.o intv.o \ - attr_scan.o base64_code.o sock_empty_wait.o attr_print0.c attr_scan0.c + attr_scan.o base64_code.o HDRS = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \ dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_mysql.h \ dict_ni.h dict_nis.h dict_nisplus.h dir_forest.h events.h \ @@ -84,7 +84,7 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \ mystrtok sigdelay translit valid_hostname vstream_popen \ vstring vstring_vstream doze select_bug stream_test mac_expand \ watchdog unescape hex_quote name_mask rand_sleep sane_time ctable \ - inet_addr_list attr_print attr_scan base64_code attr_print0 attr_scan0 + inet_addr_list attr_print attr_scan base64_code LIB_DIR = ../../lib INC_DIR = ../../include @@ -303,16 +303,6 @@ base64_code: $(LIB) $@.o $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o -attr_print0: $(LIB) $@.o - mv $@.o junk - $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) - mv junk $@.o - -attr_scan0: $(LIB) $@.o - mv $@.o junk - $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) - mv junk $@.o - depend: $(MAKES) (sed '1,/^# do not edit/!d' Makefile.in; \ set -e; for i in [a-z][a-z0-9]*.c; do \ @@ -367,11 +357,6 @@ attr_scan_test: attr_print attr_scan attr_scan.ref diff attr_scan.ref attr_scan.tmp rm -f attr_scan.tmp -attr_scan0_test: attr_print0 attr_scan0 attr_scan0.ref - (./attr_print0 2>&3 | (sleep 1; ./attr_scan0)) >attr_scan0.tmp 2>&1 3>&1 - diff attr_scan0.ref attr_scan0.tmp - rm -f attr_scan0.tmp - DB_TYPE = `../postconf/postconf -h default_database_type` dict_test: dict_open testdb dict_test.in dict_test.ref @@ -406,14 +391,6 @@ attr_print.o: htable.h attr_print.o: base64_code.h attr_print.o: vstring.h attr_print.o: attr.h -attr_print0.o: attr_print0.c -attr_print0.o: sys_defs.h -attr_print0.o: msg.h -attr_print0.o: mymalloc.h -attr_print0.o: vstream.h -attr_print0.o: vbuf.h -attr_print0.o: htable.h -attr_print0.o: attr.h attr_scan.o: attr_scan.c attr_scan.o: sys_defs.h attr_scan.o: msg.h @@ -424,15 +401,6 @@ attr_scan.o: vstring.h attr_scan.o: htable.h attr_scan.o: base64_code.h attr_scan.o: attr.h -attr_scan0.o: attr_scan0.c -attr_scan0.o: sys_defs.h -attr_scan0.o: msg.h -attr_scan0.o: mymalloc.h -attr_scan0.o: vstream.h -attr_scan0.o: vbuf.h -attr_scan0.o: vstring.h -attr_scan0.o: htable.h -attr_scan0.o: attr.h base64_code.o: base64_code.c base64_code.o: sys_defs.h base64_code.o: msg.h @@ -1011,10 +979,6 @@ skipblanks.o: sys_defs.h skipblanks.o: stringops.h skipblanks.o: vstring.h skipblanks.o: vbuf.h -sock_empty_wait.o: sock_empty_wait.c -sock_empty_wait.o: sys_defs.h -sock_empty_wait.o: msg.h -sock_empty_wait.o: iostuff.h spawn_command.o: spawn_command.c spawn_command.o: sys_defs.h spawn_command.o: msg.h diff --git a/postfix/src/util/attr.h b/postfix/src/util/attr.h index 55fce306e..1033b53b3 100644 --- a/postfix/src/util/attr.h +++ b/postfix/src/util/attr.h @@ -52,18 +52,6 @@ extern int attr_vprint(VSTREAM *, int, va_list); extern int attr_scan(VSTREAM *, int,...); extern int attr_vscan(VSTREAM *, int, va_list); - /* - * attr_print0.c. - */ -extern int attr_print0(VSTREAM *, int,...); -extern int attr_vprint0(VSTREAM *, int, va_list); - - /* - * attr_scan0.c. - */ -extern int attr_scan0(VSTREAM *, int,...); -extern int attr_vscan0(VSTREAM *, int, va_list); - /* * Attribute names for testing the compatibility of the read and write * routines. diff --git a/postfix/src/util/attr_print0.c b/postfix/src/util/attr_print0.c deleted file mode 100644 index aa9bd5443..000000000 --- a/postfix/src/util/attr_print0.c +++ /dev/null @@ -1,194 +0,0 @@ -/*++ -/* NAME -/* attr_print0 3 -/* SUMMARY -/* send attributes over byte stream -/* SYNOPSIS -/* #include -/* -/* int attr_print0(fp, flags, type, name, ...) -/* VSTREAM fp; -/* int flags; -/* int type; -/* char *name; -/* -/* int attr_vprint0(fp, flags, ap) -/* VSTREAM fp; -/* int flags; -/* va_list ap; -/* DESCRIPTION -/* attr_print0() takes zero or more (name, value) simple attributes -/* or (name, count, value) list attributes, and converts its input -/* to a byte stream that can be recovered with attr_scan0(). The stream -/* is not flushed. -/* -/* attr_vprint0() provides an alternate interface that is convenient -/* for calling from within variadoc functions. -/* -/* Attributes are sent in the requested order as specified with the -/* attr_print0() argument list. This routine satisfies the formatting -/* rules as outlined in attr_scan0(3). -/* -/* Arguments: -/* .IP fp -/* Stream to write the result to. -/* .IP flags -/* The bit-wise OR of zero or more of the following. -/* .RS -/* .IP ATTR_FLAG_MORE -/* After sending the requested attributes, leave the output stream in -/* a state that is usable for more attribute sending operations on -/* the same output attribute list. -/* By default, attr_print0() automatically appends an attribute list -/* terminator when it has sent the last requested attribute. -/* .RE -/* .IP type -/* The type determines the arguments that follow. -/* .RS -/* .IP "ATTR_TYPE_NUM (char *, int)" -/* This argument is followed by an attribute name and an integer. -/* .IP "ATTR_TYPE_STR (char *, char *)" -/* This argument is followed by an attribute name and a null-terminated -/* string. -/* .IP "ATTR_TYPE_HASH (HTABLE *)" -/* The content of the hash table is sent as a sequence of string-valued -/* attributes with names equal to the hash table lookup key. -/* .IP ATTR_TYPE_END -/* This terminates the attribute list. -/* .RE -/* DIAGNOSTICS -/* The result value is 0 in case of success, VSTREAM_EOF in case -/* of trouble. -/* -/* Panic: interface violation. All system call errors are fatal. -/* SEE ALSO -/* attr_scan0(3) recover attributes from byte stream -/* LICENSE -/* .ad -/* .fi -/* The Secure Mailer license must be distributed with this software. -/* AUTHOR(S) -/* Wietse Venema -/* IBM T.J. Watson Research -/* P.O. Box 704 -/* Yorktown Heights, NY 10598, USA -/*--*/ - -/* System library. */ - -#include -#include - -/* Utility library. */ - -#include -#include -#include -#include -#include - -/* attr_vprint0 - send attribute list to stream */ - -int attr_vprint0(VSTREAM *fp, int flags, va_list ap) -{ - const char *myname = "attr_print0"; - int attr_type; - char *attr_name; - unsigned int_val; - char *str_val; - HTABLE_INFO **ht_info_list; - HTABLE_INFO **ht; - - /* - * Sanity check. - */ - if (flags & ~ATTR_FLAG_ALL) - msg_panic("%s: bad flags: 0x%x", myname, flags); - - /* - * Iterate over all (type, name, value) triples, and produce output on - * the fly. - */ - while ((attr_type = va_arg(ap, int)) != ATTR_TYPE_END) { - switch (attr_type) { - case ATTR_TYPE_NUM: - attr_name = va_arg(ap, char *); - vstream_fwrite(fp, attr_name, strlen(attr_name)); - int_val = va_arg(ap, int); - vstream_fprintf(fp, "%u", (unsigned) int_val); - VSTREAM_PUTC('\0', fp); - if (msg_verbose) - msg_info("send attr %s = %u", attr_name, int_val); - break; - case ATTR_TYPE_STR: - attr_name = va_arg(ap, char *); - vstream_fwrite(fp, attr_name, strlen(attr_name)); - str_val = va_arg(ap, char *); - vstream_fwrite(fp, str_val, strlen(str_val)); - if (msg_verbose) - msg_info("send attr %s = %s", attr_name, str_val); - break; - case ATTR_TYPE_HASH: - ht_info_list = htable_list(va_arg(ap, HTABLE *)); - for (ht = ht_info_list; *ht; ht++) { - vstream_fwrite(fp, ht[0]->key, strlen(ht[0]->key)); - vstream_fwrite(fp, ht[0]->value, strlen(ht[0]->value)); - if (msg_verbose) - msg_info("send attr name %s value %s", - ht[0]->key, ht[0]->value); - } - myfree((char *) ht_info_list); - break; - default: - msg_panic("%s: unknown type code: %d", myname, attr_type); - } - } - if ((flags & ATTR_FLAG_MORE) == 0) - VSTREAM_PUTC('\0', fp); - return (vstream_ferror(fp)); -} - -int attr_print0(VSTREAM *fp, int flags,...) -{ - va_list ap; - int ret; - - va_start(ap, flags); - ret = attr_vprint0(fp, flags, ap); - va_end(ap); - return (ret); -} - -#ifdef TEST - - /* - * Proof of concept test program. Mirror image of the attr_scan0 test - * program. - */ -#include - -int main(int unused_argc, char **argv) -{ - HTABLE *table = htable_create(1); - - msg_vstream_init(argv[0], VSTREAM_ERR); - msg_verbose = 1; - htable_enter(table, "foo-name", mystrdup("foo-value")); - htable_enter(table, "bar-name", mystrdup("bar-value")); - attr_print0(VSTREAM_OUT, ATTR_FLAG_NONE, - ATTR_TYPE_NUM, ATTR_NAME_NUM, 4711, - ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee", - ATTR_TYPE_HASH, table, - ATTR_TYPE_END); - attr_print0(VSTREAM_OUT, ATTR_FLAG_NONE, - ATTR_TYPE_NUM, ATTR_NAME_NUM, 4711, - ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee", - ATTR_TYPE_END); - if (vstream_fflush(VSTREAM_OUT) != 0) - msg_fatal("write error: %m"); - - htable_free(table, myfree); - return (0); -} - -#endif diff --git a/postfix/src/util/attr_scan0.c b/postfix/src/util/attr_scan0.c deleted file mode 100644 index 7e3d98bbf..000000000 --- a/postfix/src/util/attr_scan0.c +++ /dev/null @@ -1,407 +0,0 @@ -/*++ -/* NAME -/* attr_scan0 3 -/* SUMMARY -/* recover attributes from byte stream -/* SYNOPSIS -/* #include -/* -/* int attr_scan0(fp, flags, type, name, ...) -/* VSTREAM fp; -/* int flags; -/* int type; -/* char *name; -/* -/* int attr_vscan0(fp, flags, ap) -/* VSTREAM fp; -/* int flags; -/* va_list ap; -/* DESCRIPTION -/* attr_scan0() takes zero or more (name, value) request attributes -/* and recovers the attribute values from the byte stream that was -/* possibly generated by attr_print0(). -/* -/* attr_vscan0() provides an alternative interface that is convenient -/* for calling from within a variadic function. -/* -/* The input stream is formatted as follows, where (item)* stands -/* for zero or more instances of the specified item, and where -/* (item1 | item2) stands for choice: -/* -/* .in +5 -/* attr-list :== simple-attr* null -/* .br -/* simple-attr :== attr-name null attr-value null -/* .br -/* attr-name :== any string not containing null -/* .br -/* attr-value :== any string not containing null -/* .br -/* null :== the ASCII null character -/* .in -/* -/* All attribute names and attribute values are sent as null terminated -/* strings. Each string must be no longer than 2*var_line_limit -/* characters. The formatting rules favor implementations in C. -/* -/* Normally, attributes must be received in the sequence as specified with -/* the attr_scan0() argument list. The input stream may contain additional -/* attributes at any point in the input stream, including additional -/* instances of requested attributes. -/* -/* Additional input attributes or input attribute instances are silently -/* skipped over, unless the ATTR_FLAG_EXTRA processing flag is specified -/* (see below). This allows for some flexibility in the evolution of -/* protocols while still providing the option of being strict where -/* this is desirable. -/* -/* Arguments: -/* .IP fp -/* Stream to recover the input attributes from. -/* .IP flags -/* The bit-wise OR of zero or more of the following. -/* .RS -/* .IP ATTR_FLAG_MISSING -/* Log a warning when the input attribute list terminates before all -/* requested attributes are recovered. It is always an error when the -/* input stream ends without the newline attribute list terminator. -/* .IP ATTR_FLAG_EXTRA -/* Log a warning and stop attribute recovery when the input stream -/* contains an attribute that was not requested. This includes the -/* case of additional instances of a requested attribute. -/* .IP ATTR_FLAG_MORE -/* After recovering the requested attributes, leave the input stream -/* in a state that is usable for more attr_scan0() operations from the -/* same input attribute list. -/* By default, attr_scan0() skips forward past the input attribute list -/* terminator. -/* .IP ATTR_FLAG_STRICT -/* For convenience, this value combines both ATTR_FLAG_MISSING and -/* ATTR_FLAG_EXTRA. -/* .IP ATTR_FLAG_NONE -/* For convenience, this value requests none of the above. -/* .RE -/* .IP type -/* The type argument determines the arguments that follow. -/* .RS -/* .IP "ATTR_TYPE_NUM (char *, int *)" -/* This argument is followed by an attribute name and an integer pointer. -/* .IP "ATTR_TYPE_STR (char *, VSTRING *)" -/* This argument is followed by an attribute name and a VSTRING pointer. -/* .IP "ATTR_TYPE_HASH (HTABLE *)" -/* All further input attributes are processed as string attributes. -/* No specific attribute sequence is enforced. -/* All attributes up to the attribute list terminator are read, -/* but only the first instance of each attribute is stored. -/* .sp -/* The attribute string values are stored in the hash table under -/* keys equal to the attribute name (obtained from the input stream). -/* Values from the input stream are added to the hash table. Existing -/* hash table entries are not replaced. -/* .sp -/* N.B. This construct must be followed by an ATTR_TYPE_END argument. -/* .IP ATTR_TYPE_END -/* This argument terminates the requested attribute list. -/* .RE -/* BUGS -/* ATTR_TYPE_HASH accepts attributes with arbitrary names from possibly -/* untrusted sources. This is unsafe, unless the resulting table is -/* queried only with known to be good attribute names. -/* DIAGNOSTICS -/* attr_scan0() and attr_vscan0() return -1 when malformed input is -/* detected (string too long, incomplete line, missing end marker). -/* Otherwise, the result value is the number of attributes that were -/* successfully recovered from the input stream (a hash table counts -/* as the number of entries stored into the table). -/* -/* Panic: interface violation. All system call errors are fatal. -/* SEE ALSO -/* attr_print0(3) send attributes over byte stream. -/* LICENSE -/* .ad -/* .fi -/* The Secure Mailer license must be distributed with this software. -/* AUTHOR(S) -/* Wietse Venema -/* IBM T.J. Watson Research -/* P.O. Box 704 -/* Yorktown Heights, NY 10598, USA -/*--*/ - -/* System library. */ - -#include -#include -#include - -/* Utility library. */ - -#include -#include -#include -#include -#include -#include -#include - -/* Application specific. */ - -#define STR(x) vstring_str(x) -#define LEN(x) VSTRING_LEN(x) - -/* attr_scan0_string - pull a string from the input stream */ - -static int attr_scan0_string(VSTREAM *fp, VSTRING *plain_buf, const char *context) -{ - extern int var_line_limit; /* XXX */ - int limit = var_line_limit * 2; - int ch; - - if ((ch = vstring_get_null_bound(plain_buf, fp, limit)) == VSTREAM_EOF) { - msg_warn("premature end-of-input from %s while reading %s", - VSTREAM_PATH(fp), context); - return (-1); - } - if (ch != 0) { - msg_warn("string length > %d characters from %s while reading %s", - limit, VSTREAM_PATH(fp), context); - return (-1); - } - if (msg_verbose) - msg_info("%s: %s", context, *STR(plain_buf) ? STR(plain_buf) : "(end)"); - return (ch); -} - -/* attr_scan0_number - pull a number from the input stream */ - -static int attr_scan0_number(VSTREAM *fp, unsigned *ptr, VSTRING *str_buf, - const char *context) -{ - char junk = 0; - int ch; - - if ((ch = attr_scan0_string(fp, str_buf, context)) < 0) - return (-1); - if (sscanf(STR(str_buf), "%u%c", ptr, &junk) != 1 || junk != 0) { - msg_warn("malformed numerical data from %s while reading %s: %.100s", - VSTREAM_PATH(fp), context, STR(str_buf)); - return (-1); - } - return (ch); -} - -/* attr_vscan0 - receive attribute list from stream */ - -int attr_vscan0(VSTREAM *fp, int flags, va_list ap) -{ - const char *myname = "attr_scan0"; - static VSTRING *str_buf = 0; - static VSTRING *name_buf = 0; - int wanted_type = -1; - char *wanted_name; - unsigned int *number; - VSTRING *string; - HTABLE *hash_table; - int ch; - int conversions; - - /* - * Sanity check. - */ - if (flags & ~ATTR_FLAG_ALL) - msg_panic("%s: bad flags: 0x%x", myname, flags); - - /* - * Initialize. - */ - if (str_buf == 0) { - str_buf = vstring_alloc(10); - name_buf = vstring_alloc(10); - } - - /* - * Iterate over all (type, name, value) triples. - */ - for (conversions = 0; /* void */ ; conversions++) { - - /* - * Determine the next attribute type and attribute name on the - * caller's wish list. - * - * If we're reading into a hash table, we already know that the - * attribute value is string-valued, and we get the attribute name - * from the input stream instead. This is secure only when the - * resulting table is queried with known to be good attribute names. - */ - if (wanted_type != ATTR_TYPE_HASH) { - wanted_type = va_arg(ap, int); - if (wanted_type == ATTR_TYPE_END) { - if ((flags & ATTR_FLAG_MORE) != 0) - return (conversions); - wanted_name = "(list terminator)"; - } else if (wanted_type == ATTR_TYPE_HASH) { - wanted_name = "(any attribute name or list terminator)"; - hash_table = va_arg(ap, HTABLE *); - if (va_arg(ap, int) !=ATTR_TYPE_END) - msg_panic("%s: ATTR_TYPE_HASH not followed by ATTR_TYPE_END", - myname); - } else { - wanted_name = va_arg(ap, char *); - } - } - - /* - * Locate the next attribute of interest in the input stream. - */ - for (;;) { - - /* - * Get the name of the next attribute. Hitting EOF is always bad. - * Hitting the end-of-input early is OK if the caller is prepared - * to deal with missing inputs. - */ - if (msg_verbose) - msg_info("%s: wanted attribute: %s", - VSTREAM_PATH(fp), wanted_name); - if ((ch = attr_scan0_string(fp, name_buf, - "input attribute name")) == VSTREAM_EOF) - return (-1); - if (LEN(name_buf) == 0) { - if (wanted_type == ATTR_TYPE_END - || wanted_type == ATTR_TYPE_HASH) - return (conversions); - if ((flags & ATTR_FLAG_MISSING) != 0) - msg_warn("missing attribute %s in input from %s", - wanted_name, VSTREAM_PATH(fp)); - return (conversions); - } - - /* - * See if the caller asks for this attribute. - */ - if (wanted_type == ATTR_TYPE_HASH - || (wanted_type != ATTR_TYPE_END - && strcmp(wanted_name, STR(name_buf)) == 0)) - break; - if ((flags & ATTR_FLAG_EXTRA) != 0) { - msg_warn("spurious attribute %s in input from %s", - STR(name_buf), VSTREAM_PATH(fp)); - return (conversions); - } - - /* - * Skip over this attribute. The caller does not ask for it. - */ - (void) attr_scan0_string(fp, string, "input attribute value"); - } - - /* - * Do the requested conversion. - */ - switch (wanted_type) { - case ATTR_TYPE_NUM: - number = va_arg(ap, unsigned int *); - if ((ch = attr_scan0_number(fp, number, str_buf, - "input attribute value")) < 0) - return (-1); - break; - case ATTR_TYPE_STR: - string = va_arg(ap, VSTRING *); - if ((ch = attr_scan0_string(fp, string, - "input attribute value")) < 0) - return (-1); - break; - case ATTR_TYPE_HASH: - if ((ch = attr_scan0_string(fp, str_buf, - "input attribute value")) < 0) - return (-1); - if (htable_locate(hash_table, STR(name_buf)) != 0) { - if ((flags & ATTR_FLAG_EXTRA) != 0) { - msg_warn("duplicate attribute %s in input from %s", - STR(name_buf), VSTREAM_PATH(fp)); - return (conversions); - } - } else { - htable_enter(hash_table, STR(name_buf), - mystrdup(STR(str_buf))); - } - break; - default: - msg_panic("%s: unknown type code: %d", myname, wanted_type); - } - } -} - -/* attr_scan0 - read attribute list from stream */ - -int attr_scan0(VSTREAM *fp, int flags,...) -{ - va_list ap; - int ret; - - va_start(ap, flags); - ret = attr_vscan0(fp, flags, ap); - va_end(ap); - return (ret); -} - -#ifdef TEST - - /* - * Proof of concept test program. Mirror image of the attr_scan0 test - * program. - */ -#include - -int var_line_limit = 2048; - -int main(int unused_argc, char **used_argv) -{ - VSTRING *str_val = vstring_alloc(1); - HTABLE *table = htable_create(1); - HTABLE_INFO **ht_info_list; - HTABLE_INFO **ht; - int int_val; - int ret; - - msg_verbose = 1; - msg_vstream_init(used_argv[0], VSTREAM_ERR); - if ((ret = attr_scan0(VSTREAM_IN, - ATTR_FLAG_STRICT, - ATTR_TYPE_NUM, ATTR_NAME_NUM, &int_val, - ATTR_TYPE_STR, ATTR_NAME_STR, str_val, - ATTR_TYPE_HASH, table, - ATTR_TYPE_END)) > 2) { - vstream_printf("%s %d\n", ATTR_NAME_NUM, int_val); - vstream_printf("%s %s\n", ATTR_NAME_STR, STR(str_val)); - ht_info_list = htable_list(table); - for (ht = ht_info_list; *ht; ht++) - vstream_printf("(hash) %s %s\n", ht[0]->key, ht[0]->value); - myfree((char *) ht_info_list); - } else { - vstream_printf("return: %d\n", ret); - } - if ((ret = attr_scan0(VSTREAM_IN, - ATTR_FLAG_STRICT, - ATTR_TYPE_NUM, ATTR_NAME_NUM, &int_val, - ATTR_TYPE_STR, ATTR_NAME_STR, str_val, - ATTR_TYPE_END)) == 2) { - vstream_printf("%s %d\n", ATTR_NAME_NUM, int_val); - vstream_printf("%s %s\n", ATTR_NAME_STR, STR(str_val)); - ht_info_list = htable_list(table); - for (ht = ht_info_list; *ht; ht++) - vstream_printf("(hash) %s %s\n", ht[0]->key, ht[0]->value); - myfree((char *) ht_info_list); - } else { - vstream_printf("return: %d\n", ret); - } - if (vstream_fflush(VSTREAM_OUT) != 0) - msg_fatal("write error: %m"); - - vstring_free(str_val); - htable_free(table, myfree); - - return (0); -} - -#endif diff --git a/postfix/src/util/iostuff.h b/postfix/src/util/iostuff.h index ac9681b1d..7da0f297d 100644 --- a/postfix/src/util/iostuff.h +++ b/postfix/src/util/iostuff.h @@ -29,9 +29,6 @@ extern int timed_write(int, void *, unsigned, int, void *); extern void doze(unsigned); extern void rand_sleep(unsigned, unsigned); extern int duplex_pipe(int *); -extern int sock_empty_wait(int, int); -extern int sock_maximize_send_lowat(int); -extern void sock_set_send_lowat(int, int); #define BLOCKING 0 #define NON_BLOCKING 1 diff --git a/postfix/src/util/sock_empty_wait.c b/postfix/src/util/sock_empty_wait.c deleted file mode 100644 index 302993d94..000000000 --- a/postfix/src/util/sock_empty_wait.c +++ /dev/null @@ -1,182 +0,0 @@ -/*++ -/* NAME -/* sock_empty_wait 3 -/* SUMMARY -/* wait until socket send buffer is near empty -/* SYNOPSIS -/* #include -/* -/* int sock_empty_wait(fd, timeout) -/* int fd; -/* int timeout; -/* AUXILIARY ROUTINES -/* int sock_maximize_send_lowat(fd) -/* int fd; -/* -/* void sock_set_send_lowat(fd, send_lowat) -/* int fd; -/* int send_lowat; -/* DESCRIPTION -/* sock_empty_wait() blocks the process until the specified socket's -/* send buffer is near empty, in the hope that the contents of the -/* next write() operation will not be merged with preceding data. -/* -/* sock_maximize_send_lowat() maximizes the socket send buffer -/* low-water mark, which controls how much free buffer space must -/* be available before the socket is considered writable. -/* The result value is the old low-water mark value. -/* -/* sock_set_send_lowat() sets the socket send buffer low-water mark -/* to the specified value. -/* -/* Arguments: -/* .IP fd -/* File descriptor in the range 0..FD_SETSIZE. -/* .IP timeout -/* If positive, deadline in seconds. A zero value effects a poll. -/* A negative value means wait until something happens. -/* DIAGNOSTICS -/* All system call errors are fatal. -/* -/* A zero result means success. When the specified deadline is -/* exceeded, sock_empty_wait() returns -1 and sets errno to ETIMEDOUT. -/* BUGS -/* Linux knows better and does not allow the application to -/* control the send buffer low-water mark. -/* LICENSE -/* .ad -/* .fi -/* The Secure Mailer license must be distributed with this software. -/* AUTHOR(S) -/* Wietse Venema -/* IBM T.J. Watson Research -/* P.O. Box 704 -/* Yorktown Heights, NY 10598, USA -/*--*/ - -/* System library. */ - -#include -#include -#include -#include -#include - -/* Utility library. */ - -#include -#include - -/* sock_maximize_send_lowat - maximize the send buffer low-water mark */ - -int sock_maximize_send_lowat(int fd) -{ - char *myname = "sock_maximize_send_lowat"; - int send_buffer_size; - int saved_low_water_mark; - int want_low_water_mark; - int got_low_water_mark; - SOCKOPT_SIZE optlen; - - /* - * Get the send buffer size. - */ - optlen = sizeof(send_buffer_size); - if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, - (char *) &send_buffer_size, &optlen) < 0) - msg_fatal("%s: getsockopt SO_SNDBUF: %m", myname); - - /* - * Save the send buffer low-water mark. - */ - optlen = sizeof(saved_low_water_mark); - if (getsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, - (char *) &saved_low_water_mark, &optlen) < 0) - msg_fatal("%s: getsockopt SO_SNDLOWAT: %m", myname); - - /* - * Max out the send buffer low-water mark. - */ - want_low_water_mark = send_buffer_size; - if (setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, - (char *) &want_low_water_mark, - sizeof(want_low_water_mark)) < 0) - if (errno != ENOPROTOOPT) - msg_fatal("%s: setsockopt SO_SNDLOWAT: %m", myname); - - /* - * Make debugging a bit easier. - */ - if (msg_verbose) { - optlen = sizeof(got_low_water_mark); - if (getsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, - (char *) &got_low_water_mark, &optlen) < 0) - msg_fatal("%s: getsockopt SO_SNDLOWAT: %m", myname); - msg_info("%s: send buffer %d, low-water mark was %d, wanted %d, got %d", - myname, send_buffer_size, saved_low_water_mark, - want_low_water_mark, got_low_water_mark); - - } - return (saved_low_water_mark); -} - -/* sock_set_send_lowat - restore socket send buffer low-water mark */ - -void sock_set_send_lowat(int fd, int want_low_water_mark) -{ - char *myname = "sock_set_send_lowat"; - int got_low_water_mark; - SOCKOPT_SIZE optlen; - - /* - * Set the send buffer low-water mark. - */ - if (setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, - (char *) &want_low_water_mark, - sizeof(want_low_water_mark)) < 0) - if (errno != ENOPROTOOPT) - msg_fatal("%s: setsockopt SO_SNDLOWAT: %m", myname); - - /* - * Make debugging a bit easier. - */ - if (msg_verbose) { - optlen = sizeof(got_low_water_mark); - if (getsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, - (char *) &got_low_water_mark, &optlen) < 0) - msg_fatal("%s: getsockopt SO_SNDLOWAT: %m", myname); - msg_info("%s: low-water mark wanted %d, got %d", - myname, want_low_water_mark, got_low_water_mark); - } -} - -/* sock_empty_wait - wait until socket send buffer is near empty */ - -int sock_empty_wait(int fd, int timeout) -{ - int saved_errno; - int saved_low_water_mark; - int result; - - /* - * Max out the send buffer low-water mark. - */ - saved_low_water_mark = sock_maximize_send_lowat(fd); - - /* - * Wait until the socket is considered writable. - */ - result = write_wait(fd, timeout); - - /* - * Restore the send buffer low-water mark. - */ - saved_errno = errno; - sock_set_send_lowat(fd, saved_low_water_mark); - errno = saved_errno; - - /* - * Done. - */ - return (result); -} diff --git a/postfix/src/util/vstring_vstream.c b/postfix/src/util/vstring_vstream.c index 2f644bf1d..078d255e1 100644 --- a/postfix/src/util/vstring_vstream.c +++ b/postfix/src/util/vstring_vstream.c @@ -27,11 +27,6 @@ /* VSTRING *vp; /* VSTREAM *fp; /* int bound; -/* -/* int vstring_get_null_bound(vp, fp, bound) -/* VSTRING *vp; -/* VSTREAM *fp; -/* int bound; /* DESCRIPTION /* The routines in this module each read one newline or null-terminated /* string from an input stream. In all cases the result is either the @@ -46,7 +41,7 @@ /* vstring_get_null() reads a null-terminated string from the named /* stream. /* -/* the vstring_get_bound() routines read no more +/* vstring_get_bound() and vstring_get_nonl_bound() read no more /* than \fIbound\fR characters. Otherwise they behave like the /* unbounded versions documented above. /* DIAGNOSTICS @@ -159,22 +154,6 @@ int vstring_get_nonl_bound(VSTRING *vp, VSTREAM *fp, int bound) return (c == '\n' ? c : VSTRING_GET_RESULT(vp)); } -/* vstring_get_null_bound - read null-terminated string from file */ - -int vstring_get_null_bound(VSTRING *vp, VSTREAM *fp, int bound) -{ - int c; - - if (bound <= 0) - msg_panic("vstring_get_nonl_bound: invalid bound %d", bound); - - VSTRING_RESET(vp); - while (bound-- > 0 && (c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != 0) - VSTRING_ADDCH(vp, c); - VSTRING_TERMINATE(vp); - return (c == 0 ? c : VSTRING_GET_RESULT(vp)); -} - #ifdef TEST /* diff --git a/postfix/src/util/vstring_vstream.h b/postfix/src/util/vstring_vstream.h index 68bd8106d..897167ca6 100644 --- a/postfix/src/util/vstring_vstream.h +++ b/postfix/src/util/vstring_vstream.h @@ -24,7 +24,6 @@ extern int vstring_get_nonl(VSTRING *, VSTREAM *); extern int vstring_get_null(VSTRING *, VSTREAM *); extern int vstring_get_bound(VSTRING *, VSTREAM *, int); extern int vstring_get_nonl_bound(VSTRING *, VSTREAM *, int); -extern int vstring_get_null_bound(VSTRING *, VSTREAM *, int); /* * Backwards compatibility for code that still uses the vstring_fgets() diff --git a/postfix/src/virtual/virtual.c b/postfix/src/virtual/virtual.c index 7968dcc28..14c388e8a 100644 --- a/postfix/src/virtual/virtual.c +++ b/postfix/src/virtual/virtual.c @@ -70,11 +70,9 @@ /* numerical user ID values that may be specified in any /* \fBvirtual_owner_maps\fR or \fBvirtual_uid_maps\fR. /* SECURITY -/* .ad -/* .fi /* The virtual delivery agent is not security sensitive, provided -/* that the lookup tables with recipient user/group ID information are -/* adequately protected. This program is not designed to run chrooted. +/* that the lookup tables with recipient information are adequately +/* protected. This program is not designed to run chrooted. /* STANDARDS /* RFC 822 (ARPA Internet Text Messages) /* DIAGNOSTICS @@ -140,7 +138,7 @@ /* This setting is ignored with \fBmaildir\fR style delivery, /* because such deliveries are safe without explicit locks. /* -/* Use the command \fBpostconf -l\fR to find out what locking methods +/* Use the command \fBpostconf -m\fR to find out what locking methods /* are available on your system. /* .IP \fBdeliver_lock_attempts\fR /* Limit the number of attempts to acquire an exclusive lock