be issued in an SMTP session (ex.: NOOP, VRFY, ETRN, RSET).
Problem report by Michael Ju. Tokarev @ tls.msk.ru. Files:
global/mail_params.h, smtpd/smtpd.c.
+
+20000407
+
+ Multi-platform build support: use the makelinks shell script
+ to build a shadow tree with symlinks to the source files.
+
+20000413
+
+ Portability: more MacOS X patches by Gerben Wierda.
+
+ Bugfix: RFC 822 requires the presence of at least one
+ destination message header. The cleanup daemon now generates
+ a generic "To: undisclosed-recipients:;" message header
+ when no destination header is present. The header content
+ is specified with the undisclosed_recipients_header parameter.
+ Problem pointed out by Geoff Gibbs, UK-Human Genome Mapping
+ Project-Resource Centre.
+
+20000416
+
+ Workaround: allow <(comment)> as SMTP MAIL FROM address.
or something closely resemblant.
On Solaris, the "make" command and other utilities for software
-development are in /usr/ccs/bin, so you MUST have /usr/ccs/bin
-in your command search path.
+development are in /usr/ccs/bin, so you MUST have /usr/ccs/bin in
+your command search path.
+
+If you need to build Postfix for multiple architectures, use the
+makelinks shell script to build a shadow tree with symbolic links
+to the source files.
+
+ % sh makelinks `pwd` /some/where/else
If at any time in the build process you get messages like: "make:
don't know how to ..." you should be able to recover by running
DIRS = util global dns master postfix smtpstone sendmail error \
pickup cleanup smtpd local trivial-rewrite qmgr smtp bounce pipe \
showq postalias postcat postconf postdrop postkick postlock postlog \
- postmap postsuper # spawn proto man html
+ postmap postsuper # base64 spawn proto man html
default: update
Incompatible changes with snapshot-20000309
===========================================
+As required by RFC 822, Postfix now inserts a generic destination
+message header when no destination header is present. The text is
+specified via the undisclosed_recipients_header configuration
+parameter (default: "To: undisclosed-recipients:;").
+
The Postfix sendmail command now treats a line with only `.' as
the end of input, for the sake of sendmail compatibility. To disable
this feature, specify the sendmail-compatible `-i' or `-oi' flags
+WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+===============================================================
+
+Do not use this code. In its present form, the cyrus SASL library
+software is light years away from production quality - not enough
+documentation to figure out how the software is supposed to work,
+and not enough error checking to find out why it fails. That is
+unacceptable for a security-sensitive application.
+
+Contrary to expectation, this code works only LINUX. If you build
+Postfix+SASL on other systems, the software builds without trouble,
+but crashes in mysterious ways when you attempt to use it, and can
+be made to work only with a considerable amount of tweaking.
+
Introduction
============
The Postfix SASL support according to RFC 2554 was originally
implemented by Till Franke of SuSE Rhein/Main AG. The present code
-is a trimmed-down implementation of only the bare necessities for
-SMTP clients and servers. When receiving mail, Postfix logs the
-client-provided username and sender address to the maillog file,
-but does not include that information in message headers.
+is a much trimmed-down implementation of only the bare necessities
+for SMTP clients and servers. When receiving mail, Postfix logs
+the client-provided username and sender address to the maillog
+file, but does not include that information in message headers.
+It is no-one's business what username and authentication method
+the poster was using in order to access the mail server.
Building the SASL library
=========================
ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/
-Other SASL libraries may require some changes. All the library
-specific code is in smtp_sasl_glue.c and in smtpd_sasl_glue.c.
-
IMPORTANT: if you install the sasl libraries as per the default,
you will have to symlink /usr/lib/sasl -> /usr/local/lib/sasl.
-This is not my idea - complain to the sasl people.
Building Postfix with SASL authentication support
=================================================
-To build Postfix with SASL authentication support, given that the
-SASL include files are in /usr/local/include, and that the SASL
-libraries are in /usr/local/lib:
+To build Postfix with SASL authentication support, the following
+assumes that the SASL include files are in /usr/local/include, and
+that the SASL libraries are in /usr/local/lib.
+
+On some systems this generates the necessary Makefile definitions:
% make makefiles CCARGS=-DUSE_SASL_AUTH" -I/usr/local/include" \
AUXLIBS="-L/usr/local/lib -lsasl"
+On Solaris 2.x you need to specify run-time link information,
+otherwise ld.so will not find the SASL shared library:
+
+ % make makefiles CCARGS=-DUSE_SASL_AUTH" -I/usr/local/include" \
+ AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lsasl"
+
Enabling SASL authentication in the SMTP server
===============================================
smtpd_recipient_restrictions =
permit_mynetworks permit_sasl_authenticated ...
-In usr/local/lib/sasl/smtpd.conf you need to specify what authentication
-mechanisms the server will support, for example:
+In /usr/local/lib/sasl/smtpd.conf you need to specify what authentication
+mechanism the server will support, for example:
+
+ pwcheck_method: shadow
+
+This will use the Linux shadow passwd file, which is in fact the
+only way that I was able to test, but which is undesirable from a
+security point of view because it uses clear-text passwords.
- pwcheck_method: {PAM, kerberos_v4, passwd, shadow, sasldb}
+To test, connect to the SMTP server, and you should be able to have
+a conversation like this:
-/etc/sasldb is a db (dbm) database. In order to make all this work
-with chrooted operation, you may have to copy files into chroot
-jail: password files, PAM libraries, etc.
+ 220 server.host.name ESMTP Postfix
+ EHLO client.host.name
+ 250-server.host.name
+ 250-PIPELINING
+ 250-SIZE 10240000
+ 250-ETRN
+ 250-AUTH DIGEST-MD5 PLAIN CRAM-MD5
+ 250 8BITMIME
+ AUTH PLAIN dGVzdAB0ZXN0AHRlc3RwYXNz
+ 235 Authentication successful
-If PAM is used, the PAM service name is `smtp'. The SASL service
-name is `smtp', too.
+Instead of dGVzdAB0ZXN0AHRlc3RwYXNz, specify the base64 encoded
+form of username\0username\0password. The example above is for a
+user named test with password testpass.
Enabling SASL authentication in the SMTP client
===============================================
-Turn on client-side SASl authentication, and specify a table with
+Turn on client-side SASL authentication, and specify a table with
per-host username and password information.
/etc/postfix/main.cf:
The SASL password file is opened before the SMTP server enters the
optional chroot jail, so there is no need to copy the sasl_passwd
-file.
+file into /var/spool/postfix/etc/postfix.
--- /dev/null
+-TALIAS_TOKEN
+-TARGV
+-TBH_TABLE
+-TBINHASH
+-TBINHASH_INFO
+-TBOUNCE_STAT
+-TCLEANUP_STATE
+-TCLIENT_LIST
+-TCLNT_STREAM
+-TCONFIG_BOOL_FN_TABLE
+-TCONFIG_BOOL_TABLE
+-TCONFIG_INT_FN_TABLE
+-TCONFIG_INT_TABLE
+-TCONFIG_STR_FN_TABLE
+-TCONFIG_STR_TABLE
+-TDELIVER_ATTR
+-TDELIVER_REQUEST
+-TDICT
+-TDICT_DB
+-TDICT_DBM
+-TDICT_ENV
+-TDICT_HT
+-TDICT_LDAP
+-TDICT_MYSQL
+-TDICT_NI
+-TDICT_NIS
+-TDICT_NISPLUS
+-TDICT_NODE
+-TDICT_OPEN_INFO
+-TDICT_PCRE
+-TDICT_REGEXP
+-TDICT_REGEXP_RULE
+-TDICT_UNIX
+-TDNS_FIXED
+-TDNS_REPLY
+-TDNS_RR
+-TDOMAIN_LIST
+-TEXPAND_ATTR
+-TFILE
+-TFORWARD_INFO
+-THEADER_OPTS
+-THOST
+-THTABLE
+-THTABLE_INFO
+-TINET_ADDR_LIST
+-TINT_TABLE
+-TLOCAL_EXP
+-TLOCAL_STATE
+-TMAC_EXP
+-TMAC_HEAD
+-TMAC_PARSE
+-TMAIL_PRINT
+-TMAIL_SCAN
+-TMAPS
+-TMASTER_PROC
+-TMASTER_SERV
+-TMASTER_STATUS
+-TMBLOCK
+-TMKMAP
+-TMKMAP_OPEN_INFO
+-TMULTI_SERVER
+-TMVECT
+-TMYSQL_NAME
+-TNAMADR_LIST
+-TNAME_MASK
+-TPEER_NAME
+-TPICKUP_INFO
+-TPIPE_ATTR
+-TPIPE_PARAMS
+-TPLMYSQL
+-TQMGR_ENTRY
+-TQMGR_MESSAGE
+-TQMGR_QUEUE
+-TQMGR_RCPT_LIST
+-TQMGR_RECIPIENT
+-TQMGR_SCAN
+-TQMGR_TRANSPORT
+-TRECIPIENT
+-TRECIPIENT_LIST
+-TREC_TYPE_NAME
+-TRESOLVE_REPLY
+-TRESPONSE
+-TSCAN_DIR
+-TSCAN_INFO
+-TSCAN_OBJ
+-TSESSION
+-TSINGLE_SERVER
+-TSINK_COMMAND
+-TSINK_STATE
+-TSMTPD_CMD
+-TSMTPD_STATE
+-TSMTPD_TOKEN
+-TSMTP_ADDR
+-TSMTP_CMD
+-TSMTP_RESP
+-TSMTP_SESSION
+-TSMTP_STATE
+-TSOCKADDR_SIZE
+-TSPAWN_ATTR
+-TSTRING_TABLE
+-TSYS_EXITS_TABLE
+-TTOK822
+-TTRIGGER_SERVER
+-TUSER_ATTR
+-TVBUF
+-TVSTREAM
+-TVSTREAM_POPEN_ARGS
+-TVSTRING
+-TWAIT_STATUS_T
+-TWATCHDOG
+-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
--- /dev/null
+SHELL = /bin/sh
+SRCS = base64encode.c base64decode.c
+OBJS = base64encode.o base64decode.o
+HDRS =
+TESTSRC =
+WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
+ -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
+ -Wunused
+DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
+CFLAGS = $(DEBUG) $(OPT) $(DEFS)
+TESTPROG=
+INC_DIR = ../include
+PROG = base64encode base64decode
+LIBS = ../lib/libglobal.a ../lib/libutil.a
+
+.c.o:; $(CC) $(CFLAGS) -c $*.c
+
+all: $(PROG)
+
+Makefile: Makefile.in
+ (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../makedefs; cat $?) >$@
+
+base64decode: base64decode.o $(LIBS)
+ $(CC) $(CFLAGS) -o $@ base64decode.o $(LIBS) $(SYSLIBS)
+
+base64encode: base64encode.o $(LIBS)
+ $(CC) $(CFLAGS) -o $@ base64encode.o $(LIBS) $(SYSLIBS)
+
+test: $(TESTPROG)
+
+update: ../bin/base64encode ../bin/base64decode
+
+../bin/base64encode: base64encode
+ cp $? $@
+
+../bin/base64decode: base64decode
+ cp $? $@
+
+printfck: $(OBJS) $(PROG)
+ rm -rf printfck
+ mkdir printfck
+ sed '1,/^# do not edit/!d' Makefile >printfck/Makefile
+ set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done
+ cd printfck; make "INC_DIR=../../include" `cd ..; ls *.o`
+
+lint:
+ lint $(DEFS) $(SRCS) $(LINTFIX)
+
+clean:
+ rm -f *.o *core $(PROG) $(TESTPROG) junk
+ rm -rf printfck
+
+tidy: clean
+
+depend: $(MAKES)
+ (sed '1,/^# do not edit/!d' Makefile.in; \
+ set -e; for i in [a-z][a-z0-9]*.c; do \
+ $(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
+ -e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
+ done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
+
+# do not edit below this line - it is generated by 'make depend'
+base64decode.o: base64decode.c
+base64decode.o: ../include/sys_defs.h
+base64decode.o: ../include/vstring.h
+base64decode.o: ../include/vbuf.h
+base64decode.o: ../include/vstream.h
+base64decode.o: ../include/vstring_vstream.h
+base64decode.o: ../include/msg.h
+base64decode.o: ../include/msg_vstream.h
+base64encode.o: base64encode.c
+base64encode.o: ../include/sys_defs.h
+base64encode.o: ../include/vstring.h
+base64encode.o: ../include/vbuf.h
+base64encode.o: ../include/vstream.h
+base64encode.o: ../include/vstring_vstream.h
+base64encode.o: ../include/msg.h
+base64encode.o: ../include/msg_vstream.h
--- /dev/null
+/* base64decode - transform base 64 data to printable form */
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <ctype.h>
+
+/* SASL library. */
+
+#include <sasl.h>
+#include <saslutil.h>
+
+/* Utility library. */
+
+#include <vstring.h>
+#include <vstream.h>
+#include <vstring_vstream.h>
+#include <msg.h>
+#include <msg_vstream.h>
+
+/* Application-specific. */
+
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
+#define UCHAR(x) ((unsigned char *) (x))
+
+static VSTRING *escape(VSTRING *escaped, char *input, int len)
+{
+ char *cp;
+ unsigned ch;
+
+ VSTRING_RESET(escaped);
+ for (cp = input; cp < input + len; cp++) {
+ ch = *UCHAR(cp);
+ if (ISASCII(ch) && ISPRINT(ch))
+ VSTRING_ADDCH(escaped, ch);
+ else
+ vstring_sprintf_append(escaped, "\\%03o", ch);
+ }
+ VSTRING_TERMINATE(escaped);
+ return (escaped);
+}
+
+int main(int unused_argc, char **argv)
+{
+ VSTRING *input = vstring_alloc(100);
+ VSTRING *escaped = vstring_alloc(100);
+ VSTRING *result = vstring_alloc(100);
+ int len;
+
+ msg_vstream_init(argv[0], VSTREAM_ERR);
+
+ while (vstring_get_nonl(input, VSTREAM_IN) != VSTREAM_EOF) {
+ VSTRING_SPACE(result, LEN(input));
+ if (sasl_decode64(STR(input), LEN(input),
+ STR(result), &len) != SASL_OK)
+ msg_fatal("malformed input");
+ vstream_printf("%s\n", STR(escape(escaped, STR(result), len)));
+ vstream_fflush(VSTREAM_OUT);
+ }
+ return (0);
+}
--- /dev/null
+/* base64encode - transform printable form to base 64 data */
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <ctype.h>
+
+/* SASL library. */
+
+#include <sasl.h>
+#include <saslutil.h>
+
+/* Utility library. */
+
+#include <vstring.h>
+#include <vstream.h>
+#include <vstring_vstream.h>
+#include <msg.h>
+#include <msg_vstream.h>
+
+/* Application-specific. */
+
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
+#define UCHAR(x) ((unsigned char *) (x))
+
+static VSTRING *unescape(VSTRING *unescaped, VSTRING *input)
+{
+ char *cp = STR(input);
+ int ch;
+ int oval;
+ int i;
+
+ VSTRING_RESET(unescaped);
+ while ((ch = *UCHAR(cp++)) != 0) {
+ switch (ch) {
+ case '\\':
+ oval = 0;
+ for (oval = 0, i = 0; i < 3 && (ch = *UCHAR(cp)) != 0; i++) {
+ if (!ISDIGIT(ch) || ch == '8' || ch == '9')
+ break;
+ oval = (oval << 3) | (ch - '0');
+ cp++;
+ }
+ VSTRING_ADDCH(unescaped, oval);
+ break;
+ default:
+ VSTRING_ADDCH(unescaped, ch);
+ break;
+ }
+ }
+ VSTRING_TERMINATE(unescaped);
+ return (unescaped);
+}
+
+int main(int unused_argc, char **argv)
+{
+ VSTRING *input = vstring_alloc(100);
+ VSTRING *unescaped = vstring_alloc(100);
+ VSTRING *result = vstring_alloc(100);
+ int result_len;
+ int len;
+
+ msg_vstream_init(argv[0], VSTREAM_ERR);
+
+ while (vstring_get_nonl(input, VSTREAM_IN) != VSTREAM_EOF) {
+ unescape(unescaped, input);
+ result_len = ((LEN(unescaped) + 2) / 3) * 4 + 1;
+ VSTRING_SPACE(result, result_len);
+ if (sasl_encode64(STR(unescaped), LEN(unescaped), STR(result),
+ result_len, &len) != SASL_OK)
+ msg_panic("sasl_encode64 botch");
+ vstream_printf("%.*s\n", len, STR(result));
+ vstream_fflush(VSTREAM_OUT);
+ }
+ return (0);
+}
/* The \fBcleanup\fR daemon always performs the following transformations:
/* .IP \(bu
/* Insert missing message headers: (\fBResent-\fR) \fBFrom:\fR,
-/* \fBMessage-Id:\fR, and \fBDate:\fR.
+/* \fBTo:\fR, \fBMessage-Id:\fR, and \fBDate:\fR.
/* .IP \(bu
/* Extract envelope recipient addresses from (\fBResent-\fR) \fBTo:\fR,
/* \fBCc:\fR and \fBBcc:\fR message headers when no recipients are
/* Address to send a copy of each message that enters the system.
/* .IP \fBhopcount_limit\fR
/* Limit the number of \fBReceived:\fR message headers.
+/* .IP \fBrecipients_witheld_header\fR
+/* The header line that is inserted when no recipients were
+/* specified in (Resent-)To: or (Resent-)Cc: message headers.
/* .SH "Address transformations"
/* .ad
/* .fi
char *var_prop_extension; /* propagate unmatched extension */
char *var_always_bcc; /* big brother */
int var_extra_rcpt_limit; /* recipient extract limit */
+char *var_rcpt_witheld; /* recipients not disclosed */
CONFIG_INT_TABLE cleanup_int_table[] = {
VAR_HOPCOUNT_LIMIT, DEF_HOPCOUNT_LIMIT, &var_hopcount_limit, 1, 0,
VAR_HEADER_CHECKS, DEF_HEADER_CHECKS, &var_header_checks, 0, 0,
VAR_PROP_EXTENSION, DEF_PROP_EXTENSION, &var_prop_extension, 0, 0,
VAR_ALWAYS_BCC, DEF_ALWAYS_BCC, &var_always_bcc, 0, 0,
+ VAR_RCPT_WITHELD, DEF_RCPT_WITHELD, &var_rcpt_witheld, 1, 0,
0,
};
state->resent, vstring_str(state->temp1));
}
}
+
+ /*
+ * Add a missing destination header.
+ */
+#define VISIBLE_RCPT (HDR_TO | HDR_RESENT_TO | HDR_CC | HDR_RESENT_CC)
+
+ if ((state->headers_seen & VISIBLE_RCPT) == 0)
+ cleanup_out_format(state, REC_TYPE_NORM, "%s", var_rcpt_witheld);
}
/* cleanup_message - initialize message content segment */
# SPECIFY ONLY PROGRAMS THAT ARE WRITTEN TO RUN AS POSTFIX DAEMONS.
# ALL DAEMONS SPECIFIED HERE MUST SPEAK A POSTFIX-INTERNAL PROTOCOL.
#
+# DO NOT CHANGE THE ZERO PROCESS LIMIT FOR CLEANUP/BOUNCE/DEFER OR
+# POSTFIX WILL BECOME STUCK UP UNDER HEAVY LOAD
+#
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (yes) (never) (50)
#define DEF_ALWAYS_BCC ""
extern char *var_always_bcc;
+ /*
+ * What to put in the To: header when no recipients were disclosed.
+ */
+#define VAR_RCPT_WITHELD "undisclosed_recipients_header"
+#define DEF_RCPT_WITHELD "To: undisclosed-recipients:;"
+extern char *var_rcpt_witheld;
+
/*
* Standards violation: allow/permit RFC 822-style addresses in SMTP
* commands.
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
-#define DEF_MAIL_VERSION "Snapshot-20000330"
+#define DEF_MAIL_VERSION "Snapshot-20000416"
extern char *var_mail_version;
/* LICENSE
<li><a href="#metoo">Postfix sends mail to every member of a
distribution list</a>
+<li><a href="#owner-foo">Postfix ignores the owner-list alias</a>
+
</ul>
<a name="mailing_lists"><h3>Mailing lists</h3>
<li><a href="#metoo">Postfix sends mail to every member of a
distribution list</a>
+<li><a href="#owner-foo">Postfix ignores the owner-list alias</a>
+
</ul>
<a name="virtual_domains"><h3>Virtual domains</h3>
<hr>
+<a name="owner-foo"><h3>Postfix ignores the owner-list alias</h3></a>
+
+Normally, when a local alias <i>foo</i> has a companion alias
+<i>owner-foo</i>, Postfix reports delivery errors to the owner
+address rather than the message originator.
+
+<p>
+
+However, as a result of a Postfix implementation artefact, the
+owner-foo alias takes effect only after the alias expansion is
+completed.
+
+<p>
+
+Delivery problems that happen while expanding the alias, including
+delivery to commands or files, are reported to the original sender
+envelope address.
+
+<p>
+
+The reason is that bounces are sent by the Postfix queue manager,
+which does not know that the sender address is being replaced.
+
+<p>
+
+This limitation will be fixed by changing how the Postfix local
+delivery agent deals with undeliverable mail.
+
+<hr>
+
<a name="delay"><h3>Postfix responds slowly to SMTP connections</h3></a>
<dl>
The next best way is to use plain old SMTP and to authenticate the
user first, for example, with a "please login via POP before using
-SMTP" scheme. In that case, some non-Postfix software such as <a
-href="http://www.mbnet.mb.ca/howto/dynamic.htm">DRAC</a> maintains
-a Postfix-compatible access table with client IP address information:
+SMTP" scheme. In that case, some software
+maintains
+a Postfix-compatible access table with client IP address information.
+In order to make this work you need Postfix version 19991231 or later.
<p>
<p>
+N.B. Some non-Postfix software such as <a
+href="http://www.mbnet.mb.ca/howto/dynamic.htm">DRAC</a> uses
+<b>btree</b> files instead of <b>hash</b> files. In that case,
+you will have to adjust the above <b>check_client_access</b>
+restriction accordingly.
+
+<p>
+
A less preferable way is based on client IP address (for example,
a 256-block) or DNS hostname (for example, whatever.pop.isp.com).
This scheme does not authenticate the user. If you use IP/DNS-based
The following information is by Joerg Henne:
<p>
-Over here we are using the scheme <fax number>@fax.our.domain with Postfix and
-HylaFax. Here's the setup used:
+Over here we are using the scheme <fax number>@fax.our.domain
+with Postfix and HylaFax. Here's the setup used:
<p>
/etc/postfix/main.cf:
transport_maps = hash:/etc/postfix/transport
+ fax_destination_recipient_limit = 1
</pre>
<p>
+The <b>fax_destination_recipient_limit</b> entry (by Simon, Mr.
+Simix) is necessary with fax software that can't have more than
+one destination on its command line. It won't hurt otherwise.
+
+<p>
+
Specify <B>dbm</b> instead of <b>hash</b> if your system uses
<b>dbm</b> files instead of <b>db</b> files. To find out what map
types Postfix supports, use the command <b>postconf -m</b>.
: ${CC=cc}
AWK=gawk
;;
+"Mac OS".10*) SYSTYPE=MACOSX
+ # Use the native compiler by default
+ : ${CC=cc}
+ AWK=gawk
+ ;;
dcosx.1*) SYSTYPE=DCOSX1
RANLIB=echo
SYSLIBS="-lresolv -lsocket -lnsl -lc -lrpcsvc -L/usr/ucblib -lucb"
--- /dev/null
+#!/bin/sh
+
+# makelinks - create shadow tree with links to source files
+
+case $# in
+ 2) src=`cd $1 || kill $$; pwd`; dst=$2;;
+ *) echo "Usage: $0 source-dir dest-dir" 1>&2; exit 1;;
+esac
+
+test -d $dst && { echo "$0: destination directory $dst exists" 1>&2; exit 1; }
+mkdir -p $dst || exit 1
+cd $dst
+(cd $src; find . -type d -print) | xargs mkdir -p
+(cd $src; find . ! -type d -print) | while read name
+do
+ ln -s $src/$name $name
+done
#
# Normally, the table serves as input to the \fBpostmap\fR(1) command.
# The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
-# is used for fast searching by the mail system. After an update
-# it may take a minute or so before the change becomes visible.
-# Issue a \fBpostfix reload\fR command to eliminate the delay.
+# is used for fast searching by the mail system. Execute the command
+# \fBpostmap /etc/postfix/access\fR in order to rebuild the indexed
+# file after changing the access table.
#
# When the table is provided via other means such as NIS, LDAP
# or SQL, the same lookups are done as for ordinary indexed files.
-#
-# >>>>>>>>>> The program "newaliases" must be run after
-# >> NOTE >> this file is updated for any changes to
-# >>>>>>>>>> show through to Postfix.
-#
-
-# Basic system aliases -- these MUST be present
-MAILER-DAEMON: postmaster
-postmaster: root
-
-# General redirections for pseudo accounts
-bin: root
-daemon: root
-named: root
-nobody: root
-uucp: root
-www: root
-ftp-bugs: root
-postfix: root
-
-# Put your local aliases here.
-
-# Well-known aliases
-manager: root
-dumper: root
-operator: root
-abuse: postmaster
-
-# trap decode to catch security attacks
-decode: root
-
-# Person who should get root's mail
-#root: you
-
#++
# NAME
# aliases 5
# format of the Postfix alias database
# SYNOPSIS
# .fi
-# \fBpostalias\fR [\fB-c\fR \fIconfig_dir\fR] [\fB-v\fR]
-# [\fIfile_type\fR:]\fIinput_file\fR
+# \fBnewaliases\fR
# DESCRIPTION
# The \fBaliases\fR file provides a system-wide mechanism to
# redirect mail for local recipients.
#
# The file serves as input to the \fBpostalias\fR(1) command. The
# result, an indexed file in \fBdbm\fR or \fBdb\fR format, is
-# used for fast lookup by the mail system. After an update
-# it may take a minute or so before the change becomes visible.
-# Issue a \fBpostfix reload\fR command to eliminate the delay.
+# used for fast lookup by the mail system. Execute the command
+# \fBnewaliases\fR in order to rebuild the indexed file after
+# changing the Postfix alias database.
#
# The input and output file formats are expected to be compatible
# with Sendmail version 8, and are expected to be suitable for the
#
# Normally, the file serves as input to the \fBpostmap\fR(1) command.
# The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
-# is used for fast searching by the mail system. After an update
-# it may take a minute or so before the change becomes visible.
-# Issue a \fBpostfix reload\fR command to eliminate the delay.
+# is used for fast searching by the mail system. Execute the command
+# \fBpostmap /etc/postfix/canonical\fR in order to rebuild the indexed
+# file after changing the canonical table.
#
# When the table is provided via other means such as NIS, LDAP
# or SQL, the same lookups are done as for ordinary indexed files.
#
# Normally, the file serves as input to the \fBpostmap\fR(1) command.
# The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
-# is used for fast searching by the mail system. After an update
-# issue a \fBpostfix reload\fR command to make the change visible.
+# is used for fast searching by the mail system. Execute the command
+# \fBpostmap /etc/postfix/relocated\fR in order to rebuild the indexed
+# file after changing the relocated table.
#
# When the table is provided via other means such as NIS, LDAP
# or SQL, the same lookups are done as for ordinary indexed files.
#
# Normally, the file serves as input to the \fBpostmap\fR(1) command.
# The result, an indexed file in \fBdbm\fR or \fBdb\fR format, is used
-# for fast searching by the mail system. After updating this table,
-# issue the \fBpostfix reload\fR command to make the change visible.
+# for fast searching by the mail system. Execute the command
+# \fBpostmap /etc/postfix/transport\fR in order to rebuild the indexed
+# file after changing the transport table.
#
# When the table is provided via other means such as NIS, LDAP
# or SQL, the same lookups are done as for ordinary indexed files.
#
# Normally, the file serves as input to the \fBpostmap\fR(1) command.
# The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
-# is used for fast searching by the mail system. After an update
-# it may take a minute or so before the change becomes visible.
-# Issue a \fBpostfix reload\fR command to eliminate the delay.
+# is used for fast searching by the mail system. Execute the command
+# \fBpostmap /etc/postfix/virtual\fR in order to rebuild the indexed
+# file after changing the virtual table.
#
# When the table is provided via other means such as NIS, LDAP
# or SQL, the same lookups are done as for ordinary indexed files.
char *var_smtp_sasl_pwd_maps;
bool var_smtp_sasl_enable;
-bool var_smtp_sasl_anon;
#endif
return (-1);
}
if (state->helo_name != 0) {
- state->error_mask |= MAIL_ERROR_PROTOCOL;
- smtpd_chat_reply(state, "503 Duplicate HELO/EHLO");
- return (-1);
+ myfree(state->helo_name);
+ state->helo_name = 0;
}
if (argc > 2)
collapse_args(argc - 1, argv + 1);
return (-1);
}
if (state->helo_name != 0) {
- state->error_mask |= MAIL_ERROR_PROTOCOL;
- smtpd_chat_reply(state, "503 Error: duplicate HELO/EHLO");
- return (-1);
+ myfree(state->helo_name);
+ state->helo_name = 0;
}
if (argc > 2)
collapse_args(argc - 1, argv + 1);
#define PERMIT_EMPTY_ADDR 1
#define REJECT_EMPTY_ADDR 0
- if (allow_empty_addr && strcmp(STR(arg->vstrval), "<>") == 0) {
- if (msg_verbose)
- msg_info("%s: empty address", myname);
- VSTRING_RESET(arg->vstrval);
- VSTRING_TERMINATE(arg->vstrval);
- arg->strval = STR(arg->vstrval);
- return (0);
- }
-
/*
* Some mailers send RFC822-style address forms (with comments and such)
* in SMTP envelopes. We cannot blame users for this: the blame is with
/*
* Report trouble. Log a warning only if we are going to sleep+reject.
*/
- if (naddr != 1
+ if ((naddr < 1 && !allow_empty_addr)
+ || naddr > 1
|| (strict_rfc821 && (non_addr || *STR(arg->vstrval) != '<'))) {
msg_warn("Illegal address syntax from %s in %s command: %s",
state->namaddr, state->where, STR(arg->vstrval));
if (addr)
tok822_internalize(arg->vstrval, addr->head, TOK822_STR_DEFL);
else
- vstring_strcat(arg->vstrval, "");
+ vstring_strcpy(arg->vstrval, "");
arg->strval = STR(arg->vstrval);
/*
if ((state->msg_size = off_cvt_string(arg + 5)) < 0)
state->msg_size = 0;
#ifdef USE_SASL_AUTH
- } else if (strncasecmp(arg, "AUTH=", 5) == 0) {
+ } else if (var_smtpd_sasl_enable && strncasecmp(arg, "AUTH=", 5) == 0) {
if ((err = smtpd_sasl_mail_opt(state, arg + 5)) != 0) {
smtpd_chat_reply(state, "%s", err);
return (-1);
if (var_smtpd_sasl_enable)
smtpd_sasl_mail_log(state);
else
-#else
- msg_info("%s: client=%s[%s]", state->queue_id, state->name, state->addr);
#endif
+ msg_info("%s: client=%s[%s]", state->queue_id, state->name, state->addr);
/*
* Record the time of arrival and the sender envelope address.
state->sender = 0;
}
#ifdef USE_SASL_AUTH
- smtpd_sasl_mail_reset(state);
+ if (var_smtpd_sasl_enable)
+ smtpd_sasl_mail_reset(state);
#endif
}
*/
helo_reset(state);
#ifdef USE_SASL_AUTH
- smtpd_sasl_auth_reset(state);
+ if (var_smtpd_sasl_enable)
+ smtpd_sasl_auth_reset(state);
#endif
mail_reset(state);
rcpt_reset(state);
*/
state->sasl_mechanism_list = 0;
state->sasl_username = 0;
+ state->sasl_method = 0;
state->sasl_sender = 0;
state->sasl_conn = 0;
state->sasl_decoded = vstring_alloc(10);
* Security options. XXX What exactly is this supposed to be doing? The
* cyrus-sasl-1.5.15 source code has no documentation at all about this
* routine.
+ *
+ * Disallow anonymous authentication. The permit_sasl_authenticated feature
+ * is restricted to authenticated clients only.
*/
memset(&sec_props, 0, sizeof(sec_props));
sec_props.min_ssf = 0;
sec_props.max_ssf = 1; /* don't allow real SASL
* security layer */
- sec_props.security_flags = 0;
+ sec_props.security_flags = SASL_SEC_NOANONYMOUS;
sec_props.maxbufsize = 0;
sec_props.property_names = 0;
sec_props.property_values = 0;
#define IGNORE_MECHANISM_LEN ((unsigned *) 0)
if (sasl_listmech(state->sasl_conn, UNSUPPORTED_USER,
- "250-AUTH ", " ", "",
+ "", " ", "",
&state->sasl_mechanism_list,
IGNORE_MECHANISM_LEN,
&sasl_mechanism_count) != SASL_OK
{
if (state->sasl_mechanism_list) {
free(state->sasl_mechanism_list);
- state->sasl_mechanism_list = NULL;
+ state->sasl_mechanism_list = 0;
}
if (state->sasl_conn) {
sasl_dispose(&state->sasl_conn);
unsigned enc_length;
unsigned enc_length_out;
unsigned reply_len;
- char *serverout;
+ char *serverout = 0;
unsigned serveroutlen;
int result;
const char *errstr = 0;
enc_length, &enc_length_out) != SASL_OK)
msg_panic("%s: sasl_encode64 botch", myname);
free(serverout);
+ serverout = 0;
smtpd_chat_reply(state, "334 %s", STR(state->sasl_encoded));
/*
* Receive the client response. "*" means that the client gives up.
- * For now we ignore the fact that excessively long responses will be
- * truncated. To handle such responses, we need to change
+ * XXX For now we ignore the fact that excessively long responses
+ * will be truncated. To handle such responses, we need to change
* smtpd_chat_query() so that it returns an error indication.
*/
smtpd_chat_query(state);
dec_length, &serverout, &serveroutlen, &errstr);
}
+ /*
+ * Cleanup. What a horrible interface.
+ */
+ if (serverout)
+ free(serverout);
+
/*
* The authentication protocol was completed.
*/
/*
* Authentication succeeded. Find out the login name for logging and for
* accounting purposes. For the sake of completeness we also record the
- * authentication method that was used.
+ * authentication method that was used. XXX Do not free(serverout).
*/
result = sasl_getprop(state->sasl_conn, SASL_USERNAME,
(void **) &serverout);
msg_panic("%s: sasl_getprop SASL_USERNAME botch", myname);
state->sasl_username = mystrdup(serverout);
state->sasl_method = mystrdup(sasl_method);
- free(serverout);
return (0);
}
state->junk_cmds = 0;
#ifdef USE_SASL_AUTH
- smtpd_sasl_connect(state);
+ if (var_smtpd_sasl_enable)
+ smtpd_sasl_connect(state);
#endif
/*
smtpd_peer_reset(state);
#ifdef USE_SASL_AUTH
- smtpd_sasl_disconnect(state);
+ if (var_smtpd_sasl_enable)
+ smtpd_sasl_disconnect(state);
#endif
}
#define USE_DOT_LOCK
#endif
-#if defined(RHAPSODY5)
+#if defined(RHAPSODY5) || defined(MACOSX)
#define SUPPORTED
#include <sys/types.h>
#define USE_PATHS_H