2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 05:38:06 +00:00

snapshot-20000421

This commit is contained in:
Wietse Venema 2000-04-21 00:00:00 +00:00
parent 17d46ec1c0
commit d69f7e550d
21 changed files with 607 additions and 105 deletions

View File

@ -3827,3 +3827,9 @@ Apologies for any names omitted.
Added LMTP support to the smtp-source and smtp-sink utilities Added LMTP support to the smtp-source and smtp-sink utilities
so that I don't have to install Cyrus IMAP just to test so that I don't have to install Cyrus IMAP just to test
LMTP. LMTP.
20000419
Bugfix: removed the () from the tokenized representation
of RFC 822 comments, so that comments with \( or \) can be
unparsed correctly. Problem reported by Bodo Moeller.

View File

@ -2,31 +2,59 @@
# HERE JUST SERVES AS AN EXAMPLE. # HERE JUST SERVES AS AN EXAMPLE.
# #
# This file contains example settings of Postfix configuration # This file contains example settings of Postfix configuration
# parameters that control SMTP authentication # parameters that control SASL authentication.
# As of now, SASL authentication support uses the Cyrus SASL library # SMTP SERVER CONTROLS
# which is known to work on Linux and Solaris.
# The smtpd_sasl_auth_enable parameter controls whether authentication # The smtpd_sasl_auth_enable parameter controls whether authentication
# is enabled in the Postfix SMTP server. # is enabled in the Postfix SMTP server.
# #
# If a client is authenticated, then it matches the permit_sasl_authenticated # If a client is authenticated, then the permit_sasl_authenticated
# UCE restriction, which can be used to grant mail relay access. # can be used to permit relay access.
# #
# In order to enable server-side authentication, build Postfix with # In order to enable server-side authentication, build Postfix with
# SASL support, and install a configuration file /usr/lib/sasl/smtpd.conf # SASL support, and install a configuration file /usr/lib/sasl/smtpd.conf
# with as contents, for example, # with as contents, for example,
# #
# pwcheck_method: PAM # pwcheck_method: sasldb
# #
# or whatever is suitable for your environment. The PAM service name # or whatever method is suitable for your environment: PAM, shadow,
# for SASL authentication is "smtp". # whatever. If you use sasldb, you can add users with the "saslpasswd"
# command that is part of the SASL library. If you use PAM, The PAM
# service name for SASL authentication is "smtp", and adding users
# depends entirely on how PAM is set up.
# #
# If you run your SMTP server chrooted, then you need to copy the # If you run your SMTP server chrooted, then you need to copy PAM
# PAM and SASL support libraries and data files into the chroot jail. # and/or SASL support libraries and data files into the chroot jail.
# #
smtpd_sasl_auth_enable = yes smtpd_sasl_auth_enable = yes
# The smtpd_sasl_security_options parameter controls what authentication
# mechanisms the Postfix SMTP server will offer to the client. The
# list of available authentication mechanisms is system dependent.
#
# Specify zero or more of the following:
#
# noplaintext: disallow methods that use plaintext passwords
# noactive: disallow methods subject to active (non-dictionary) attack
# nodictionary: disallow methods subject to passive (dictionary) attack
# noanonymous: disallow methods that allow anonymous authentication
#
# By default, the Postfix SMTP server accepts plaintext passwords but
# not anonymous logins.
#
# Horror! It appears that clients try authentication methods in the
# order as advertised by the server (PLAIN ANONYMOUS CRAM-MD5
# ...) which means that if you disable plaintext passwords, clients
# will log in anonymously even when they would be able to use CRAM-MD5.
# So, if you disable plaintext logins, disable anonymous logins too.
# Postfix treats anonymous login as no authentication.
#
#smtpd_sasl_security_options = noanonymous, noplaintext
smtpd_sasl_security_options = noanonymous
# SMTP CLIENT CONTROLS
# The smtp_sasl_auth_enable parameter controls whether authentication # The smtp_sasl_auth_enable parameter controls whether authentication
# is enabled in the Postfix SMTP client. # is enabled in the Postfix SMTP client.
# #
@ -34,10 +62,26 @@ smtp_sasl_auth_enable = yes
# The smtp_sasl_password_maps parameter specifies the names of lookup # The smtp_sasl_password_maps parameter specifies the names of lookup
# tables with one username:password entry per remote hostname. If a # tables with one username:password entry per remote hostname. If a
# remote host has no username:password entry, then Postfix will not # remote host has no username:password entry, then the Postfix SMTP
# attempt to authenticate to the host. # client will not attempt to authenticate to the remote host.
# #
# The Postifx SMTP client opens the lookup table before going to # The Postfix SMTP client opens the lookup table before going to
# chroot jail, so you can keep the password file in /etc/postfix. # chroot jail, so you can keep the password file in /etc/postfix.
# #
smtp_auth_passwd_map = hash:/etc/postfix/saslpass smtp_auth_passwd_map = hash:/etc/postfix/saslpass
# The smtp_sasl_security_options parameter controls what authentication
# mechanisms the local Postfix SMTP client is allowed to use. The
# list of available authentication mechanisms is system dependent.
#
# Specify zero or more of the following:
#
# noplaintext: disallow methods that use plaintext passwords
# noactive: disallow methods subject to active (non-dictionary) attack
# nodictionary: disallow methods subject to passive (dictionary) attack
# noanonymous: disallow methods that allow anonymous authentication
#
# By default, the Postfix SMTP client will not use plaintext passwords.
#
#smtpd_sasl_security_options =
smtpd_sasl_security_options = noplaintext

View File

@ -63,8 +63,7 @@ LIB = libglobal.a
TESTPROG= domain_list dot_lockfile mail_addr_crunch mail_addr_find \ TESTPROG= domain_list dot_lockfile mail_addr_crunch mail_addr_find \
mail_addr_map mail_date maps mynetworks mypwd namadr_list \ mail_addr_map mail_date maps mynetworks mypwd namadr_list \
off_cvt quote_822_local rec2stream recdump resolve_clnt \ off_cvt quote_822_local rec2stream recdump resolve_clnt \
resolve_local rewrite_clnt stream2rec string_list tok822_parse \ resolve_local rewrite_clnt stream2rec string_list tok822_parse
local_transport
LIBS = ../lib/libutil.a LIBS = ../lib/libutil.a
LIB_DIR = ../lib LIB_DIR = ../lib
@ -194,6 +193,13 @@ local_transport: $(LIB) $(LIBS)
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS) $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mv junk $@.o mv junk $@.o
tests: tok822_test
tok822_test: tok822_parse tok822_parse.in tok822_parse.ref
./tok822_parse <tok822_parse.in >tok822_parse.tmp
diff tok822_parse.ref tok822_parse.tmp
rm -f tok822_parse.tmp
printfck: $(OBJS) $(PROG) printfck: $(OBJS) $(PROG)
rm -rf printfck rm -rf printfck
mkdir printfck mkdir printfck
@ -559,6 +565,7 @@ mail_queue.o: ../include/argv.h
mail_queue.o: ../include/dir_forest.h mail_queue.o: ../include/dir_forest.h
mail_queue.o: ../include/make_dirs.h mail_queue.o: ../include/make_dirs.h
mail_queue.o: ../include/split_at.h mail_queue.o: ../include/split_at.h
mail_queue.o: ../include/sane_fsops.h
mail_queue.o: file_id.h mail_queue.o: file_id.h
mail_queue.o: mail_params.h mail_queue.o: mail_params.h
mail_queue.o: mail_queue.h mail_queue.o: mail_queue.h

View File

@ -643,19 +643,30 @@ extern int var_smtpd_err_sleep;
extern int var_smtpd_junk_cmd_limit; extern int var_smtpd_junk_cmd_limit;
/* /*
* SASL authentication support. * SASL authentication support, server side.
*/ */
#define VAR_SMTPD_SASL_ENABLE "smtpd_sasl_auth_enable" #define VAR_SMTPD_SASL_ENABLE "smtpd_sasl_auth_enable"
#define DEF_SMTPD_SASL_ENABLE 0 #define DEF_SMTPD_SASL_ENABLE 0
extern bool var_smtpd_sasl_enable; extern bool var_smtpd_sasl_enable;
#define VAR_SMTPD_SASL_OPTS "smtpd_sasl_security_options"
#define DEF_SMTPD_SASL_OPTS "noanonymous"
extern char *var_smtpd_sasl_opts;
/*
* SASL authentication support, client side.
*/
#define VAR_SMTP_SASL_ENABLE "smtp_sasl_auth_enable" #define VAR_SMTP_SASL_ENABLE "smtp_sasl_auth_enable"
#define DEF_SMTP_SASL_ENABLE 0 #define DEF_SMTP_SASL_ENABLE 0
extern bool var_smtp_sasl_enable; extern bool var_smtp_sasl_enable;
#define VAR_SMTP_SASL_PWD_MAPS "smtp_sasl_password_maps" #define VAR_SMTP_SASL_PASSWD "smtp_sasl_password_maps"
#define DEF_SMTP_SASL_PWD_MAPS "" #define DEF_SMTP_SASL_PASSWD ""
extern char *var_smtp_sasl_pwd_maps; extern char *var_smtp_sasl_passwd;
#define VAR_SMTP_SASL_OPTS "smtp_sasl_security_options"
#define DEF_SMTP_SASL_OPTS "noplaintext, noanonymous"
extern char *var_smtp_sasl_opts;
#define PERMIT_SASL_AUTH "permit_sasl_authenticated" #define PERMIT_SASL_AUTH "permit_sasl_authenticated"

View File

@ -15,7 +15,7 @@
* Version of this program. * Version of this program.
*/ */
#define VAR_MAIL_VERSION "mail_version" #define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "Snapshot-20000418" #define DEF_MAIL_VERSION "Snapshot-20000421"
extern char *var_mail_version; extern char *var_mail_version;
/* LICENSE /* LICENSE

View File

@ -45,7 +45,8 @@ typedef struct TOK822 {
#define TOK822_DOMLIT 259 /* stuff between [] not nesting */ #define TOK822_DOMLIT 259 /* stuff between [] not nesting */
#define TOK822_ADDR 260 /* actually a token group */ #define TOK822_ADDR 260 /* actually a token group */
#define TOK822_STARTGRP 261 /* start of named group */ #define TOK822_STARTGRP 261 /* start of named group */
#define TOK822_MAXTOK 261 #define TOK822_COMMTEXT 262 /* comment text */
#define TOK822_MAXTOK 262
/* /*
* tok822_node.c * tok822_node.c

View File

@ -56,10 +56,13 @@ TOK822 *tok822_alloc(int type, const char *strval)
{ {
TOK822 *tp; TOK822 *tp;
#define CONTAINER_TOKEN(x) \
((x) == TOK822_ADDR || (x) == TOK822_COMMENT || (x) == TOK822_STARTGRP)
tp = (TOK822 *) mymalloc(sizeof(*tp)); tp = (TOK822 *) mymalloc(sizeof(*tp));
tp->type = type; tp->type = type;
tp->next = tp->prev = tp->head = tp->tail = tp->owner = 0; tp->next = tp->prev = tp->head = tp->tail = tp->owner = 0;
tp->vstr = (type < TOK822_MINTOK ? 0 : tp->vstr = (type < TOK822_MINTOK || CONTAINER_TOKEN(type) ? 0 :
strval == 0 ? vstring_alloc(10) : strval == 0 ? vstring_alloc(10) :
vstring_strcpy(vstring_alloc(strlen(strval) + 1), strval)); vstring_strcpy(vstring_alloc(strlen(strval) + 1), strval));
return (tp); return (tp);

View File

@ -191,8 +191,13 @@ VSTRING *tok822_internalize(VSTRING *vp, TOK822 *tree, int flags)
case TOK822_ADDR: case TOK822_ADDR:
tok822_internalize(vp, tp->head, TOK822_STR_NONE); tok822_internalize(vp, tp->head, TOK822_STR_NONE);
break; break;
case TOK822_ATOM:
case TOK822_COMMENT: case TOK822_COMMENT:
VSTRING_ADDCH(vp, '(');
tok822_internalize(vp, tp->head, TOK822_STR_NONE);
VSTRING_ADDCH(vp, ')');
break;
case TOK822_ATOM:
case TOK822_COMMTEXT:
case TOK822_QSTRING: case TOK822_QSTRING:
vstring_strcat(vp, vstring_str(tp->vstr)); vstring_strcat(vp, vstring_str(tp->vstr));
break; break;
@ -242,7 +247,12 @@ VSTRING *tok822_externalize(VSTRING *vp, TOK822 *tree, int flags)
vstring_strcat(vp, vstring_str(tp->vstr)); vstring_strcat(vp, vstring_str(tp->vstr));
break; break;
case TOK822_COMMENT: case TOK822_COMMENT:
tok822_copy_quoted(vp, vstring_str(tp->vstr), "\\\r\n"); VSTRING_ADDCH(vp, '(');
tok822_externalize(vp, tp->head, TOK822_STR_NONE);
VSTRING_ADDCH(vp, ')');
break;
case TOK822_COMMTEXT:
tok822_copy_quoted(vp, vstring_str(tp->vstr), "()\\\r\n");
break; break;
case TOK822_QSTRING: case TOK822_QSTRING:
VSTRING_ADDCH(vp, '"'); VSTRING_ADDCH(vp, '"');
@ -251,7 +261,7 @@ VSTRING *tok822_externalize(VSTRING *vp, TOK822 *tree, int flags)
break; break;
case TOK822_DOMLIT: case TOK822_DOMLIT:
VSTRING_ADDCH(vp, '['); VSTRING_ADDCH(vp, '[');
tok822_copy_quoted(vp, vstring_str(tp->vstr), "\"\\\r\n"); tok822_copy_quoted(vp, vstring_str(tp->vstr), "\\\r\n");
VSTRING_ADDCH(vp, ']'); VSTRING_ADDCH(vp, ']');
break; break;
case TOK822_STARTGRP: case TOK822_STARTGRP:
@ -316,7 +326,6 @@ TOK822 *tok822_scan(const char *str, TOK822 **tailp)
continue; continue;
if (ch == '(') { if (ch == '(') {
tp = tok822_alloc(TOK822_COMMENT, (char *) 0); tp = tok822_alloc(TOK822_COMMENT, (char *) 0);
VSTRING_ADDCH(tp->vstr, ch);
str = tok822_comment(tp, str); str = tok822_comment(tp, str);
} else if (ch == '[') { } else if (ch == '[') {
tp = tok822_alloc(TOK822_DOMLIT, (char *) 0); tp = tok822_alloc(TOK822_DOMLIT, (char *) 0);
@ -332,7 +341,13 @@ TOK822 *tok822_scan(const char *str, TOK822 **tailp)
COLLECT(tp, str, ch, !ISSPACE(ch) && !strchr(tok822_opchar, ch)); COLLECT(tp, str, ch, !ISSPACE(ch) && !strchr(tok822_opchar, ch));
tok822_quote_atom(tp); tok822_quote_atom(tp);
} }
tail = (head == 0 ? head = tp : tok822_append(tail, tp)); if (head == 0) {
head = tail = tp;
while (tail->next)
tail = tail->next;
} else {
tail = tok822_append(tail, tp);
}
} }
if (tailp) if (tailp)
*tailp = tail; *tailp = tail;
@ -451,24 +466,36 @@ static void tok822_quote_atom(TOK822 *tp)
const char *tok822_comment(TOK822 *tp, const char *str) const char *tok822_comment(TOK822 *tp, const char *str)
{ {
TOK822 *tc = 0;
int ch; int ch;
#define COMMENT_TEXT_TOKEN(t) ((t) && (t)->type == TOK822_COMMTEXT)
#define APPEND_NEW_TOKEN(tp, type, strval) \
tok822_sub_append(tp, tok822_alloc(type, strval))
while ((ch = *(unsigned char *) str) != 0) { while ((ch = *(unsigned char *) str) != 0) {
VSTRING_ADDCH(tp->vstr, ISSPACE(ch) ? ' ' : ch);
str++; str++;
if (ch == '(') { /* comments can nest! */ if (ch == '(') { /* comments can nest! */
str = tok822_comment(tp, str); if (COMMENT_TEXT_TOKEN(tc))
VSTRING_TERMINATE(tc->vstr);
tc = APPEND_NEW_TOKEN(tp, TOK822_COMMENT, (char *) 0);
str = tok822_comment(tc, str);
} else if (ch == ')') { } else if (ch == ')') {
break; break;
} else if (ch == '\\') { } else {
vstring_truncate(tp->vstr, VSTRING_LEN(tp->vstr) - 1); if (ch == '\\') {
if ((ch = *(unsigned char *) str) == 0) if ((ch = *(unsigned char *) str) == 0)
break; break;
VSTRING_ADDCH(tp->vstr, ch); str++;
str++; }
if (!COMMENT_TEXT_TOKEN(tc))
tc = APPEND_NEW_TOKEN(tp, TOK822_COMMTEXT, (char *) 0);
VSTRING_ADDCH(tc->vstr, ch);
} }
} }
VSTRING_TERMINATE(tp->vstr); if (COMMENT_TEXT_TOKEN(tc))
VSTRING_TERMINATE(tc->vstr);
return (str); return (str);
} }
@ -511,25 +538,36 @@ TOK822 *tok822_scan_addr(const char *addr)
#ifdef TEST #ifdef TEST
#include <unistd.h>
#include <vstream.h> #include <vstream.h>
#include <vstring_vstream.h> #include <vstring_vstream.h>
/* tok822_print - display token */ /* tok822_print - display token */
static void tok822_print(TOK822 *tp, int indent) static void tok822_print(TOK822 *list, int indent)
{ {
if (tp->type < TOK822_MINTOK) { TOK822 *tp;
vstream_printf("%*s %s \"%c\"\n", indent, "", "OP", tp->type);
} else if (tp->type == TOK822_ADDR) { for (tp = list; tp; tp = tp->next) {
vstream_printf("%*s %s\n", indent, "", "address"); if (tp->type < TOK822_MINTOK) {
} else { vstream_printf("%*s %s \"%c\"\n", indent, "", "OP", tp->type);
vstream_printf("%*s %s \"%s\"\n", indent, "", } else if (tp->type == TOK822_ADDR) {
tp->type == TOK822_COMMENT ? "comment" : vstream_printf("%*s %s\n", indent, "", "address");
tp->type == TOK822_ATOM ? "atom" : tok822_print(tp->head, indent + 2);
tp->type == TOK822_QSTRING ? "quoted string" : } else if (tp->type == TOK822_COMMENT) {
tp->type == TOK822_DOMLIT ? "domain literal" : vstream_printf("%*s %s\n", indent, "", "comment");
tp->type == TOK822_ADDR ? "address" : tok822_print(tp->head, indent + 2);
"unknown\n", vstring_str(tp->vstr)); } else if (tp->type == TOK822_STARTGRP) {
vstream_printf("%*s %s\n", indent, "", "group \":\"");
} else {
vstream_printf("%*s %s \"%s\"\n", indent, "",
tp->type == TOK822_COMMTEXT ? "text" :
tp->type == TOK822_ATOM ? "atom" :
tp->type == TOK822_QSTRING ? "quoted string" :
tp->type == TOK822_DOMLIT ? "domain literal" :
tp->type == TOK822_ADDR ? "address" :
"unknown\n", vstring_str(tp->vstr));
}
} }
} }
@ -537,22 +575,14 @@ int main(int unused_argc, char **unused_argv)
{ {
VSTRING *vp = vstring_alloc(100); VSTRING *vp = vstring_alloc(100);
TOK822 *list; TOK822 *list;
TOK822 *tp;
TOK822 *ap;
int indent = 0;
VSTRING *buf = vstring_alloc(100); VSTRING *buf = vstring_alloc(100);
while (vstring_fgets(buf, VSTREAM_IN)) { while (vstring_fgets_nonl(buf, VSTREAM_IN)) {
if (!isatty(vstream_fileno(VSTREAM_IN)))
vstream_printf(">>>%s<<<\n\n", vstring_str(buf));
list = tok822_parse(vstring_str(buf)); list = tok822_parse(vstring_str(buf));
for (tp = list; tp; tp = tp->next) { vstream_printf("Parse tree:\n");
tok822_print(tp, indent); tok822_print(list, 0);
if (tp->type == TOK822_ADDR) {
indent += 2;
for (ap = tp->head; ap; ap = ap->next)
tok822_print(ap, indent);
indent -= 2;
}
}
vstream_printf("\n"); vstream_printf("\n");
vstream_printf("Internalized:\n%s\n\n", vstream_printf("Internalized:\n%s\n\n",

View File

@ -0,0 +1,13 @@
wietse@porcupine.org
"wietse venema"@porcupine.org
wietse@porcupine.org
wietse @ porcupine.org
"wietse venema"@porcupine.org ("wietse ) venema")
"wietse venema" <wietse@porcupine.org>
"wietse venema"@porcupine.org ( ("wietse ) venema") )
"wietse venema"@porcupine.org
wietse\ venema@porcupine.org
"wietse venema
wietse@[stuff
wietse@["stuff]
named group: foo@bar, baz@barf;

View File

@ -0,0 +1,266 @@
>>>wietse@porcupine.org<<<
Parse tree:
address
atom "wietse"
OP "@"
atom "porcupine"
OP "."
atom "org"
Internalized:
wietse@porcupine.org
Externalized, no newlines inserted:
wietse@porcupine.org
Externalized, newlines inserted:
wietse@porcupine.org
>>>"wietse venema"@porcupine.org<<<
Parse tree:
address
quoted string "wietse venema"
OP "@"
atom "porcupine"
OP "."
atom "org"
Internalized:
wietse venema@porcupine.org
Externalized, no newlines inserted:
"wietse venema"@porcupine.org
Externalized, newlines inserted:
"wietse venema"@porcupine.org
>>>wietse@porcupine.org<<<
Parse tree:
address
atom "wietse"
OP "@"
atom "porcupine"
OP "."
atom "org"
Internalized:
wietse@porcupine.org
Externalized, no newlines inserted:
wietse@porcupine.org
Externalized, newlines inserted:
wietse@porcupine.org
>>>wietse @ porcupine.org<<<
Parse tree:
address
atom "wietse"
OP "@"
atom "porcupine"
OP "."
atom "org"
Internalized:
wietse@porcupine.org
Externalized, no newlines inserted:
wietse@porcupine.org
Externalized, newlines inserted:
wietse@porcupine.org
>>>"wietse venema"@porcupine.org ("wietse ) venema")<<<
Parse tree:
address
quoted string "wietse venema"
OP "@"
atom "porcupine"
OP "."
atom "org"
OP ","
address
atom "venema"
comment
text ""wietse "
OP ","
address
quoted string ")"
Internalized:
wietse venema@porcupine.org, venema ("wietse ), )
Externalized, no newlines inserted:
"wietse venema"@porcupine.org, venema ("wietse ), ")"
Externalized, newlines inserted:
"wietse venema"@porcupine.org,
venema ("wietse ),
")"
>>>"wietse venema" <wietse@porcupine.org><<<
Parse tree:
quoted string "wietse venema"
OP "<"
address
atom "wietse"
OP "@"
atom "porcupine"
OP "."
atom "org"
OP ">"
Internalized:
wietse venema <wietse@porcupine.org>
Externalized, no newlines inserted:
"wietse venema" <wietse@porcupine.org>
Externalized, newlines inserted:
"wietse venema" <wietse@porcupine.org>
>>>"wietse venema"@porcupine.org ( ("wietse ) venema") )<<<
Parse tree:
address
quoted string "wietse venema"
OP "@"
atom "porcupine"
OP "."
atom "org"
OP ")"
comment
text " "
comment
text ""wietse "
text " venema""
Internalized:
wietse venema@porcupine.org) ( ("wietse ) venema")
Externalized, no newlines inserted:
"wietse venema"@porcupine.org) ( ("wietse ) venema")
Externalized, newlines inserted:
"wietse venema"@porcupine.org) ( ("wietse ) venema")
>>>"wietse venema"@porcupine.org<<<
Parse tree:
address
quoted string "wietse venema"
OP "@"
atom "porcupine"
OP "."
atom "org"
Internalized:
wietse venema@porcupine.org
Externalized, no newlines inserted:
"wietse venema"@porcupine.org
Externalized, newlines inserted:
"wietse venema"@porcupine.org
>>>wietse\ venema@porcupine.org<<<
Parse tree:
address
quoted string "wietse venema"
OP "@"
atom "porcupine"
OP "."
atom "org"
Internalized:
wietse venema@porcupine.org
Externalized, no newlines inserted:
"wietse venema"@porcupine.org
Externalized, newlines inserted:
"wietse venema"@porcupine.org
>>>"wietse venema<<<
Parse tree:
address
quoted string "wietse venema"
Internalized:
wietse venema
Externalized, no newlines inserted:
"wietse venema"
Externalized, newlines inserted:
"wietse venema"
>>>wietse@[stuff<<<
Parse tree:
address
atom "wietse"
OP "@"
domain literal "stuff"
Internalized:
wietse@[stuff]
Externalized, no newlines inserted:
wietse@[stuff]
Externalized, newlines inserted:
wietse@[stuff]
>>>wietse@["stuff]<<<
Parse tree:
address
atom "wietse"
OP "@"
domain literal ""stuff"
Internalized:
wietse@["stuff]
Externalized, no newlines inserted:
wietse@["stuff]
Externalized, newlines inserted:
wietse@["stuff]
>>>named group: foo@bar, baz@barf;<<<
Parse tree:
atom "named"
atom "group"
group ":"
address
atom "foo"
OP "@"
atom "bar"
OP ","
address
atom "baz"
OP "@"
atom "barf"
OP ";"
Internalized:
named group: foo@bar, baz@barf;
Externalized, no newlines inserted:
named group: foo@bar, baz@barf;
Externalized, newlines inserted:
named group: foo@bar,
baz@barf;

View File

@ -119,6 +119,8 @@ domains with "relay access denied"</a>
<li><a href="#relay_restrict">Restricting what users can send mail to off-site destinations</a> <li><a href="#relay_restrict">Restricting what users can send mail to off-site destinations</a>
<li><a href="#backup">Configuring Postfix as backup MX host</a>
</ul> </ul>
<a name="remote_delivery"><h3>Remote delivery</h3> <a name="remote_delivery"><h3>Remote delivery</h3>
@ -1154,6 +1156,42 @@ host.
<hr> <hr>
<a name="backup"><h3>Configuring Postfix as backup MX host</h3></a>
When you are SECONDARY MX for some other domain this is all you need:
<p>
<pre>
DNS:
the.backed-up.domain.name IN MX 100 your.machine.name
/etc/postfix/main.cf:
relay_domains = the.backed-up.domain.name
</pre>
<p>
When you are PRIMARY MX for some other domain you also need:
<p>
<pre>
/etc/postfix/main.cf:
transport_maps = hash:/etc/postfix/transport
/etc/postfix/transport:
the.backed-up.domain.name smtp:[their.mail.host.name]
</pre>
<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>.
<hr>
<a name="timeouts"><h3>Mail fails consistently with timeout or lost connection</h3></a> <a name="timeouts"><h3>Mail fails consistently with timeout or lost connection</h3></a>
Every now and then, mail fails with "timed out while sending end Every now and then, mail fails with "timed out while sending end

View File

@ -331,6 +331,7 @@ maildir.o: ../include/vstring.h
maildir.o: ../include/make_dirs.h maildir.o: ../include/make_dirs.h
maildir.o: ../include/set_eugid.h maildir.o: ../include/set_eugid.h
maildir.o: ../include/get_hostname.h maildir.o: ../include/get_hostname.h
maildir.o: ../include/sane_fsops.h
maildir.o: ../include/mail_copy.h maildir.o: ../include/mail_copy.h
maildir.o: ../include/bounce.h maildir.o: ../include/bounce.h
maildir.o: ../include/sent.h maildir.o: ../include/sent.h

View File

@ -177,6 +177,7 @@ smtp_sasl_glue.o: ../include/msg.h
smtp_sasl_glue.o: ../include/mymalloc.h smtp_sasl_glue.o: ../include/mymalloc.h
smtp_sasl_glue.o: ../include/stringops.h smtp_sasl_glue.o: ../include/stringops.h
smtp_sasl_glue.o: ../include/split_at.h smtp_sasl_glue.o: ../include/split_at.h
smtp_sasl_glue.o: ../include/name_mask.h
smtp_sasl_glue.o: ../include/mail_params.h smtp_sasl_glue.o: ../include/mail_params.h
smtp_sasl_glue.o: ../include/string_list.h smtp_sasl_glue.o: ../include/string_list.h
smtp_sasl_glue.o: ../include/maps.h smtp_sasl_glue.o: ../include/maps.h
@ -193,6 +194,7 @@ smtp_sasl_proto.o: smtp_sasl_proto.c
smtp_sasl_proto.o: ../include/sys_defs.h smtp_sasl_proto.o: ../include/sys_defs.h
smtp_sasl_proto.o: ../include/msg.h smtp_sasl_proto.o: ../include/msg.h
smtp_sasl_proto.o: ../include/mymalloc.h smtp_sasl_proto.o: ../include/mymalloc.h
smtp_sasl_proto.o: ../include/mail_params.h
smtp_sasl_proto.o: smtp.h smtp_sasl_proto.o: smtp.h
smtp_sasl_proto.o: ../include/vstream.h smtp_sasl_proto.o: ../include/vstream.h
smtp_sasl_proto.o: ../include/vbuf.h smtp_sasl_proto.o: ../include/vbuf.h

View File

@ -100,6 +100,20 @@
/* .IP \fBsmtp_sasl_password_maps\fR /* .IP \fBsmtp_sasl_password_maps\fR
/* Lookup tables with per-host \fIname\fR:\fIpassword\fR entries. /* Lookup tables with per-host \fIname\fR:\fIpassword\fR entries.
/* No entry for a host means no attempt to authenticate. /* No entry for a host means no attempt to authenticate.
/* .IP \fBsmtp_sasl_security_options\fR
/* Zero or more of the following.
/* .RS
/* .IP \fBnoplaintext\fR
/* Disallow authentication methods that use plaintext passwords.
/* .IP \fBnoactive\fR
/* Disallow authentication methods that are vulnerable to non-dictionary
/* active attacks.
/* .IP \fBnodictionary\fR
/* Disallow authentication methods that are vulnerable to passive
/* dictionary attack.
/* .IP \fBnoanonymous\fR
/* Disallow anonymous logins.
/* .RE
/* .SH "Resource controls" /* .SH "Resource controls"
/* .ad /* .ad
/* .fi /* .fi
@ -218,14 +232,10 @@ char *var_fallback_relay;
char *var_bestmx_transp; char *var_bestmx_transp;
char *var_error_rcpt; char *var_error_rcpt;
int var_smtp_always_ehlo; int var_smtp_always_ehlo;
char *var_smtp_sasl_opts;
#ifdef USE_SASL_AUTH char *var_smtp_sasl_passwd;
char *var_smtp_sasl_pwd_maps;
bool var_smtp_sasl_enable; bool var_smtp_sasl_enable;
#endif
/* /*
* Global variables. smtp_errno is set by the address lookup routines and by * Global variables. smtp_errno is set by the address lookup routines and by
* the connection management routines. * the connection management routines.
@ -370,9 +380,8 @@ int main(int argc, char **argv)
VAR_FALLBACK_RELAY, DEF_FALLBACK_RELAY, &var_fallback_relay, 0, 0, VAR_FALLBACK_RELAY, DEF_FALLBACK_RELAY, &var_fallback_relay, 0, 0,
VAR_BESTMX_TRANSP, DEF_BESTMX_TRANSP, &var_bestmx_transp, 0, 0, VAR_BESTMX_TRANSP, DEF_BESTMX_TRANSP, &var_bestmx_transp, 0, 0,
VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0, VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0,
#ifdef USE_SASL_AUTH VAR_SMTP_SASL_PASSWD, DEF_SMTP_SASL_PASSWD, &var_smtp_sasl_passwd, 0, 0,
VAR_SMTP_SASL_PWD_MAPS, DEF_SMTP_SASL_PWD_MAPS, &var_smtp_sasl_pwd_maps, 0, 0, VAR_SMTP_SASL_OPTS, DEF_SMTP_SASL_OPTS, &var_smtp_sasl_opts, 0, 0,
#endif
0, 0,
}; };
static CONFIG_INT_TABLE int_table[] = { static CONFIG_INT_TABLE int_table[] = {
@ -393,9 +402,7 @@ int main(int argc, char **argv)
VAR_IGN_MX_LOOKUP_ERR, DEF_IGN_MX_LOOKUP_ERR, &var_ign_mx_lookup_err, VAR_IGN_MX_LOOKUP_ERR, DEF_IGN_MX_LOOKUP_ERR, &var_ign_mx_lookup_err,
VAR_SKIP_QUIT_RESP, DEF_SKIP_QUIT_RESP, &var_skip_quit_resp, VAR_SKIP_QUIT_RESP, DEF_SKIP_QUIT_RESP, &var_skip_quit_resp,
VAR_SMTP_ALWAYS_EHLO, DEF_SMTP_ALWAYS_EHLO, &var_smtp_always_ehlo, VAR_SMTP_ALWAYS_EHLO, DEF_SMTP_ALWAYS_EHLO, &var_smtp_always_ehlo,
#ifdef USE_SASL_AUTH
VAR_SMTP_SASL_ENABLE, DEF_SMTP_SASL_ENABLE, &var_smtp_sasl_enable, VAR_SMTP_SASL_ENABLE, DEF_SMTP_SASL_ENABLE, &var_smtp_sasl_enable,
#endif
0, 0,
}; };

View File

@ -91,6 +91,7 @@
#include <mymalloc.h> #include <mymalloc.h>
#include <stringops.h> #include <stringops.h>
#include <split_at.h> #include <split_at.h>
#include <name_mask.h>
/* /*
* Global library * Global library
@ -107,6 +108,19 @@
#ifdef USE_SASL_AUTH #ifdef USE_SASL_AUTH
/*
* Authentication security options.
*/
static NAME_MASK smtp_sasl_sec_mask[] = {
"noplaintext", SASL_SEC_NOPLAINTEXT,
"noactive", SASL_SEC_NOACTIVE,
"nodictionary", SASL_SEC_NODICTIONARY,
"noanonymous", SASL_SEC_NOANONYMOUS,
0,
};
static int smtp_sasl_sec_opts;
/* /*
* Silly little macros. * Silly little macros.
*/ */
@ -142,10 +156,17 @@ static int smtp_sasl_log(void *unused_context, int priority,
static int smtp_sasl_get_user(void *context, int unused_id, const char **result, static int smtp_sasl_get_user(void *context, int unused_id, const char **result,
unsigned *len) unsigned *len)
{ {
char *myname = "smtp_sasl_get_user";
SMTP_STATE *state = (SMTP_STATE *) context; SMTP_STATE *state = (SMTP_STATE *) context;
if (msg_verbose) if (msg_verbose)
msg_info("smtp_sasl_get_user: %s", state->sasl_username); msg_info("%s: %s", myname, state->sasl_username);
/*
* Sanity check.
*/
if (state->sasl_passwd == 0)
msg_panic("%s: no username looked up", myname);
*result = state->sasl_username; *result = state->sasl_username;
if (len) if (len)
@ -158,17 +179,20 @@ static int smtp_sasl_get_user(void *context, int unused_id, const char **result,
static int smtp_sasl_get_passwd(sasl_conn_t *conn, void *context, static int smtp_sasl_get_passwd(sasl_conn_t *conn, void *context,
int id, sasl_secret_t **psecret) int id, sasl_secret_t **psecret)
{ {
char *myname = "smtp_sasl_get_passwd";
SMTP_STATE *state = (SMTP_STATE *) context; SMTP_STATE *state = (SMTP_STATE *) context;
int len; int len;
if (msg_verbose) if (msg_verbose)
msg_info("smtp_sasl_get_passwd: %s", state->sasl_passwd); msg_info("%s: %s", myname, state->sasl_passwd);
/* /*
* Sanity check. * Sanity check.
*/ */
if (!conn || !psecret || id != SASL_CB_PASS) if (!conn || !psecret || id != SASL_CB_PASS)
return (SASL_BADPARAM); return (SASL_BADPARAM);
if (state->sasl_passwd == 0)
msg_panic("%s: no password looked up", myname);
/* /*
* Convert the password into a counted string. * Convert the password into a counted string.
@ -207,12 +231,12 @@ int smtp_sasl_passwd_lookup(SMTP_STATE *state)
msg_info("%s: host `%s' user `%s' pass `%s'", msg_info("%s: host `%s' user `%s' pass `%s'",
myname, state->session->host, myname, state->session->host,
state->sasl_username, state->sasl_passwd); state->sasl_username, state->sasl_passwd);
return(1); return (1);
} else { } else {
if (msg_verbose) if (msg_verbose)
msg_info("%s: host `%s' no auth info found", msg_info("%s: host `%s' no auth info found",
myname, state->session->host); myname, state->session->host);
return(0); return (0);
} }
} }
@ -234,18 +258,23 @@ void smtp_sasl_initialize(void)
*/ */
if (smtp_sasl_passwd_map) if (smtp_sasl_passwd_map)
msg_panic("smtp_sasl_initialize: repeated call"); msg_panic("smtp_sasl_initialize: repeated call");
if (*var_smtp_sasl_pwd_maps == 0) if (*var_smtp_sasl_passwd == 0)
msg_fatal("specify password table via the `%s' configuration parameter", msg_fatal("specify a password table via the `%s' configuration parameter",
VAR_SMTP_SASL_PWD_MAPS); VAR_SMTP_SASL_PASSWD);
/* /*
* Open the per-host password table and initialize the SASL library. Use * Open the per-host password table and initialize the SASL library. Use
* shared locks for reading, just in case someone updates the table. * shared locks for reading, just in case someone updates the table.
*/ */
smtp_sasl_passwd_map = maps_create("smtp_sasl_passwd", smtp_sasl_passwd_map = maps_create("smtp_sasl_passwd",
var_smtp_sasl_pwd_maps, DICT_FLAG_LOCK); var_smtp_sasl_passwd, DICT_FLAG_LOCK);
if (sasl_client_init(callbacks) != SASL_OK) if (sasl_client_init(callbacks) != SASL_OK)
msg_fatal("SASL library initialization"); msg_fatal("SASL library initialization");
/*
* Configuration parameters.
*/
smtp_sasl_sec_opts = name_mask(smtp_sasl_sec_mask, var_smtp_sasl_opts);
} }
/* smtp_sasl_connect - per-session client initialization */ /* smtp_sasl_connect - per-session client initialization */
@ -291,7 +320,6 @@ void smtp_sasl_start(SMTP_STATE *state)
state->sasl_callbacks, NULL_SECFLAGS, state->sasl_callbacks, NULL_SECFLAGS,
(sasl_conn_t **) &state->sasl_conn) != SASL_OK) (sasl_conn_t **) &state->sasl_conn) != SASL_OK)
msg_fatal("per-session SASL client initialization"); msg_fatal("per-session SASL client initialization");
smtp_sasl_passwd_lookup(state);
/* /*
* Per-session security properties. XXX This routine is not sufficiently * Per-session security properties. XXX This routine is not sufficiently
@ -301,7 +329,7 @@ void smtp_sasl_start(SMTP_STATE *state)
sec_props.min_ssf = 0; sec_props.min_ssf = 0;
sec_props.max_ssf = 1; /* don't allow real SASL sec_props.max_ssf = 1; /* don't allow real SASL
* security layer */ * security layer */
sec_props.security_flags = 0; sec_props.security_flags = smtp_sasl_sec_opts;
sec_props.maxbufsize = 0; sec_props.maxbufsize = 0;
sec_props.property_names = 0; sec_props.property_names = 0;
sec_props.property_values = 0; sec_props.property_values = 0;
@ -352,7 +380,7 @@ int smtp_sasl_authenticate(SMTP_STATE *state, VSTRING *why)
if (result != SASL_OK && result != SASL_CONTINUE) { if (result != SASL_OK && result != SASL_CONTINUE) {
vstring_sprintf(why, "cannot SASL authenticate to server %s: %s", vstring_sprintf(why, "cannot SASL authenticate to server %s: %s",
state->session->namaddr, state->session->namaddr,
sasl_errstring(result, NO_SASL_LANGLIST, sasl_errstring(result, NO_SASL_LANGLIST,
NO_SASL_OUTLANG)); NO_SASL_OUTLANG));
return (-1); return (-1);
} }
@ -384,7 +412,7 @@ int smtp_sasl_authenticate(SMTP_STATE *state, VSTRING *why)
* Step through the authentication protocol until the server tells us * Step through the authentication protocol until the server tells us
* that we are done. * that we are done.
*/ */
while ((resp = smtp_chat_resp(state))->code % 100 == 3) { while ((resp = smtp_chat_resp(state))->code / 100 == 3) {
/* /*
* Process a server challenge. * Process a server challenge.
@ -395,7 +423,7 @@ int smtp_sasl_authenticate(SMTP_STATE *state, VSTRING *why)
VSTRING_SPACE(state->sasl_decoded, serverinlen); VSTRING_SPACE(state->sasl_decoded, serverinlen);
if (sasl_decode64(line, serverinlen, if (sasl_decode64(line, serverinlen,
STR(state->sasl_decoded), &enc_length) != SASL_OK) { STR(state->sasl_decoded), &enc_length) != SASL_OK) {
vstring_sprintf(why, "unable to decode SASL challenge from %s", vstring_sprintf(why, "malformed SASL challenge from server %s",
state->session->namaddr); state->session->namaddr);
return (-1); return (-1);
} }
@ -407,8 +435,10 @@ int smtp_sasl_authenticate(SMTP_STATE *state, VSTRING *why)
STR(state->sasl_decoded), enc_length, STR(state->sasl_decoded), enc_length,
NO_SASL_INTERACTION, &clientout, &clientoutlen); NO_SASL_INTERACTION, &clientout, &clientoutlen);
if (result != SASL_OK && result != SASL_CONTINUE) if (result != SASL_OK && result != SASL_CONTINUE)
msg_warn("%s: smtp SASL authentication step failed", msg_warn("SASL authentication failed to server %s: %s",
state->session->namaddr); state->session->namaddr,
sasl_errstring(result, NO_SASL_LANGLIST,
NO_SASL_OUTLANG));
/* /*
* Send a client response. * Send a client response.
@ -434,8 +464,8 @@ int smtp_sasl_authenticate(SMTP_STATE *state, VSTRING *why)
* We completed the authentication protocol. * We completed the authentication protocol.
*/ */
if (resp->code / 100 != 2) { if (resp->code / 100 != 2) {
vstring_sprintf(why, "unable to SASL authenticate with %s", vstring_sprintf(why, "SASL authentication failed; server %s said: %s",
state->session->namaddr); state->session->namaddr, resp->str);
return (0); return (0);
} }
return (1); return (1);

View File

@ -202,6 +202,7 @@ smtpd_sasl_glue.o: ../include/sys_defs.h
smtpd_sasl_glue.o: ../include/msg.h smtpd_sasl_glue.o: ../include/msg.h
smtpd_sasl_glue.o: ../include/mymalloc.h smtpd_sasl_glue.o: ../include/mymalloc.h
smtpd_sasl_glue.o: ../include/namadr_list.h smtpd_sasl_glue.o: ../include/namadr_list.h
smtpd_sasl_glue.o: ../include/name_mask.h
smtpd_sasl_glue.o: ../include/mail_params.h smtpd_sasl_glue.o: ../include/mail_params.h
smtpd_sasl_glue.o: ../include/smtp_stream.h smtpd_sasl_glue.o: ../include/smtp_stream.h
smtpd_sasl_glue.o: ../include/vstring.h smtpd_sasl_glue.o: ../include/vstring.h

View File

@ -64,6 +64,20 @@
/* Enable per-session authentication as per RFC 2554 (SASL). /* Enable per-session authentication as per RFC 2554 (SASL).
/* This functionality is available only when explicitly selected /* This functionality is available only when explicitly selected
/* at program build time and explicitly enabled at runtime. /* at program build time and explicitly enabled at runtime.
/* .IP \fBsmtpd_sasl_security_options\fR
/* Zero or more of the following.
/* .RS
/* .IP \fBnoplaintext\fR
/* Disallow authentication methods that use plaintext passwords.
/* .IP \fBnoactive\fR
/* Disallow authentication methods that are vulnerable to non-dictionary
/* active attacks.
/* .IP \fBnodictionary\fR
/* Disallow authentication methods that are vulnerable to passive
/* dictionary attack.
/* .IP \fBnoanonymous\fR
/* Disallow anonymous logins.
/* .RE
/* .SH Miscellaneous /* .SH Miscellaneous
/* .ad /* .ad
/* .fi /* .fi
@ -320,6 +334,7 @@ char *var_local_rcpt_maps;
bool var_allow_untrust_route; bool var_allow_untrust_route;
int var_smtpd_junk_cmd_limit; int var_smtpd_junk_cmd_limit;
bool var_smtpd_sasl_enable; bool var_smtpd_sasl_enable;
char *var_smtpd_sasl_opts;
/* /*
* Global state, for stand-alone mode queue file cleanup. When this is * Global state, for stand-alone mode queue file cleanup. When this is
@ -1403,6 +1418,7 @@ int main(int argc, char **argv)
VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps, 0, 0, VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps, 0, 0,
VAR_ALIAS_MAPS, DEF_ALIAS_MAPS, &var_alias_maps, 0, 0, VAR_ALIAS_MAPS, DEF_ALIAS_MAPS, &var_alias_maps, 0, 0,
VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps, 0, 0, VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps, 0, 0,
VAR_SMTPD_SASL_OPTS, DEF_SMTPD_SASL_OPTS, &var_smtpd_sasl_opts, 0, 0,
0, 0,
}; };

View File

@ -768,19 +768,6 @@ static int reject_unknown_mailhost(SMTPD_STATE *state, char *name,
return (SMTPD_CHECK_DUNNO); return (SMTPD_CHECK_DUNNO);
} }
#ifdef USE_SASL_AUTH
/* permit_sasl_auth - OK for authenticated connection */
static int permit_sasl_auth(SMTPD_STATE *state)
{
if (state->sasl_username)
return (SMTPD_CHECK_OK);
return (SMTPD_CHECK_DUNNO);
}
#endif
/* check_relay_domains - OK/FAIL for message relaying */ /* check_relay_domains - OK/FAIL for message relaying */
static int check_relay_domains(SMTPD_STATE *state, char *recipient, static int check_relay_domains(SMTPD_STATE *state, char *recipient,
@ -1680,7 +1667,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
cpp[1], CHECK_RELAY_DOMAINS); cpp[1], CHECK_RELAY_DOMAINS);
#ifdef USE_SASL_AUTH #ifdef USE_SASL_AUTH
} else if (strcasecmp(name, PERMIT_SASL_AUTH) == 0) { } else if (strcasecmp(name, PERMIT_SASL_AUTH) == 0) {
status = permit_sasl_auth(state); status = permit_sasl_auth(state, SMTPD_CHECK_OK, SMTPD_CHECK_DUNNO);
#endif #endif
} else if (strcasecmp(name, REJECT_UNKNOWN_RCPTDOM) == 0) { } else if (strcasecmp(name, REJECT_UNKNOWN_RCPTDOM) == 0) {
if (state->recipient) if (state->recipient)

View File

@ -90,6 +90,7 @@
#include <msg.h> #include <msg.h>
#include <mymalloc.h> #include <mymalloc.h>
#include <namadr_list.h> #include <namadr_list.h>
#include <name_mask.h>
/* Global library. */ /* Global library. */
@ -140,6 +141,17 @@ static sasl_callback_t callbacks[] = {
{SASL_CB_LIST_END, 0, 0} {SASL_CB_LIST_END, 0, 0}
}; };
static NAME_MASK smtpd_sasl_mask[] = {
"noplaintext", SASL_SEC_NOPLAINTEXT,
"noactive", SASL_SEC_NOACTIVE,
"nodictionary", SASL_SEC_NODICTIONARY,
"noanonymous", SASL_SEC_NOANONYMOUS,
0,
};
static int smtpd_sasl_opts;
/* smtpd_sasl_initialize - per-process initialization */ /* smtpd_sasl_initialize - per-process initialization */
void smtpd_sasl_initialize(void) void smtpd_sasl_initialize(void)
@ -150,6 +162,11 @@ void smtpd_sasl_initialize(void)
*/ */
if (sasl_server_init(callbacks, "smtpd") != SASL_OK) if (sasl_server_init(callbacks, "smtpd") != SASL_OK)
msg_fatal("SASL per-process initialization failed"); msg_fatal("SASL per-process initialization failed");
/*
* Configuration parameters.
*/
smtpd_sasl_opts = name_mask(smtpd_sasl_mask, var_smtpd_sasl_opts);
} }
/* smtpd_sasl_connect - per-connection initialization */ /* smtpd_sasl_connect - per-connection initialization */
@ -195,7 +212,7 @@ void smtpd_sasl_connect(SMTPD_STATE *state)
sec_props.min_ssf = 0; sec_props.min_ssf = 0;
sec_props.max_ssf = 1; /* don't allow real SASL sec_props.max_ssf = 1; /* don't allow real SASL
* security layer */ * security layer */
sec_props.security_flags = SASL_SEC_NOANONYMOUS; sec_props.security_flags = smtpd_sasl_opts;
sec_props.maxbufsize = 0; sec_props.maxbufsize = 0;
sec_props.property_names = 0; sec_props.property_names = 0;
sec_props.property_values = 0; sec_props.property_values = 0;

View File

@ -16,6 +16,7 @@ extern void smtpd_sasl_connect(SMTPD_STATE *);
extern void smtpd_sasl_disconnect(SMTPD_STATE *); extern void smtpd_sasl_disconnect(SMTPD_STATE *);
extern char *smtpd_sasl_authenticate(SMTPD_STATE *, const char *, const char *); extern char *smtpd_sasl_authenticate(SMTPD_STATE *, const char *, const char *);
extern void smtpd_sasl_logout(SMTPD_STATE *); extern void smtpd_sasl_logout(SMTPD_STATE *);
extern int permit_sasl_auth(SMTPD_STATE *, int, int);
/* LICENSE /* LICENSE
/* .ad /* .ad

View File

@ -24,6 +24,11 @@
/* /*
/* void smtpd_sasl_mail_reset(state) /* void smtpd_sasl_mail_reset(state)
/* SMTPD_STATE *state; /* SMTPD_STATE *state;
/*
/* static int permit_sasl_auth(state, authenticated, unauthenticated)
/* SMTPD_STATE *state;
/* int authenticated;
/* int unauthenticated;
/* DESCRIPTION /* DESCRIPTION
/* This module contains random chunks of code that implement /* This module contains random chunks of code that implement
/* the SMTP protocol interface for SASL negotiation. The goal /* the SMTP protocol interface for SASL negotiation. The goal
@ -43,6 +48,9 @@
/* smtpd_sasl_mail_reset() performs cleanup for the SASL-specific /* smtpd_sasl_mail_reset() performs cleanup for the SASL-specific
/* AUTH=sender option to the MAIL FROM command. /* AUTH=sender option to the MAIL FROM command.
/* /*
/* permit_sasl_auth() permits access from an authenticated client.
/* This test fails for clients that use anonymous authentication.
/*
/* Arguments: /* Arguments:
/* .IP state /* .IP state
/* SMTP session context. /* SMTP session context.
@ -53,6 +61,10 @@
/* .IP sender /* .IP sender
/* Sender address from the AUTH=sender option in the MAIL FROM /* Sender address from the AUTH=sender option in the MAIL FROM
/* command. /* command.
/* .IP authenticated
/* Result for authenticated client.
/* .IP unauthenticated
/* Result for unauthenticated client.
/* DIAGNOSTICS /* DIAGNOSTICS
/* All errors are fatal. /* All errors are fatal.
/* LICENSE /* LICENSE
@ -201,4 +213,13 @@ void smtpd_sasl_mail_reset(SMTPD_STATE *state)
} }
} }
/* permit_sasl_auth - OK for authenticated connection */
int permit_sasl_auth(SMTPD_STATE *state, int ifyes, int ifnot)
{
if (state->sasl_method && strcasecmp(state->sasl_method, "anonymous"))
return (ifyes);
return (ifnot);
}
#endif #endif