]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
snapshot-20000421
authorWietse Venema <wietse@porcupine.org>
Fri, 21 Apr 2000 00:00:00 +0000 (00:00 +0000)
committerWietse Venema <wietse@porcupine.org>
Thu, 17 Jan 2013 23:10:38 +0000 (18:10 -0500)
21 files changed:
postfix/HISTORY
postfix/conf/sample-auth.cf
postfix/global/Makefile.in
postfix/global/mail_params.h
postfix/global/mail_version.h
postfix/global/tok822.h
postfix/global/tok822_node.c
postfix/global/tok822_parse.c
postfix/global/tok822_parse.in [new file with mode: 0644]
postfix/global/tok822_parse.ref [new file with mode: 0644]
postfix/html/faq.html
postfix/local/Makefile.in
postfix/smtp/Makefile.in
postfix/smtp/smtp.c
postfix/smtp/smtp_sasl_glue.c
postfix/smtpd/Makefile.in
postfix/smtpd/smtpd.c
postfix/smtpd/smtpd_check.c
postfix/smtpd/smtpd_sasl_glue.c
postfix/smtpd/smtpd_sasl_glue.h
postfix/smtpd/smtpd_sasl_proto.c

index 5f17ecb36b989965d706c611a6d6000ccaefe028..3c10bba81664b7c6c0eb99400a78bffd96e6c2f8 100644 (file)
@@ -3827,3 +3827,9 @@ Apologies for any names omitted.
        Added LMTP support to the smtp-source and smtp-sink utilities
        so that I don't have to install Cyrus IMAP just to test
        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.
index a9b8f7c179ec5362880e4fb1c736f41206cc9ba1..eaf66feec6a345c8acacc4365c177b3112a61dc0 100644 (file)
@@ -2,31 +2,59 @@
 # HERE JUST SERVES AS AN EXAMPLE.
 #
 # 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
-# which is known to work on Linux and Solaris.
+# SMTP SERVER CONTROLS
 
 # The smtpd_sasl_auth_enable parameter controls whether authentication
 # is enabled in the Postfix SMTP server.
 #
-# If a client is authenticated, then it matches the permit_sasl_authenticated
-# UCE restriction, which can be used to grant mail relay access.
+# If a client is authenticated, then the permit_sasl_authenticated
+# can be used to permit relay access.
 #
 # In order to enable server-side authentication, build Postfix with
 # SASL support, and install a configuration file /usr/lib/sasl/smtpd.conf
 # with as contents, for example,
 #
-#      pwcheck_method:  PAM
+#      pwcheck_method:  sasldb
 #
-# or whatever is suitable for your environment. The PAM service name
-# for SASL authentication is "smtp".
+# or whatever method is suitable for your environment: PAM, shadow,
+# 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
-# PAM and SASL support libraries and data files into the chroot jail.
+# If you run your SMTP server chrooted, then you need to copy PAM
+# and/or SASL support libraries and data files into the chroot jail.
 #
 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
 # 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
 # tables with one username:password entry per remote hostname.  If a
-# remote host has no username:password entry, then Postfix will not
-# attempt to authenticate to the host.
+# remote host has no username:password entry, then the Postfix SMTP
+# 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.
 #
 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
index 0b207fe35fe07e1d97151bf7349a4fc1d0a70656..724159e88c2feb0bfc3512338204ae4cb0020a8f 100644 (file)
@@ -63,8 +63,7 @@ LIB   = libglobal.a
 TESTPROG= domain_list dot_lockfile mail_addr_crunch mail_addr_find \
        mail_addr_map mail_date maps mynetworks mypwd namadr_list \
        off_cvt quote_822_local rec2stream recdump resolve_clnt \
-       resolve_local rewrite_clnt stream2rec string_list tok822_parse \
-       local_transport
+       resolve_local rewrite_clnt stream2rec string_list tok822_parse
 
 LIBS   = ../lib/libutil.a
 LIB_DIR        = ../lib
@@ -194,6 +193,13 @@ local_transport: $(LIB) $(LIBS)
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
        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)
        rm -rf printfck
        mkdir printfck
@@ -559,6 +565,7 @@ mail_queue.o: ../include/argv.h
 mail_queue.o: ../include/dir_forest.h
 mail_queue.o: ../include/make_dirs.h
 mail_queue.o: ../include/split_at.h
+mail_queue.o: ../include/sane_fsops.h
 mail_queue.o: file_id.h
 mail_queue.o: mail_params.h
 mail_queue.o: mail_queue.h
index 130cdd8a7dbd77bf82e5d0113d9145f1539a2c67..22b8c6d969e8462341e9ffe58135af89da4614b3 100644 (file)
@@ -643,19 +643,30 @@ extern int var_smtpd_err_sleep;
 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 DEF_SMTPD_SASL_ENABLE  0
 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 DEF_SMTP_SASL_ENABLE   0
 extern bool var_smtp_sasl_enable;
 
-#define VAR_SMTP_SASL_PWD_MAPS "smtp_sasl_password_maps"
-#define DEF_SMTP_SASL_PWD_MAPS ""
-extern char *var_smtp_sasl_pwd_maps;
+#define VAR_SMTP_SASL_PASSWD   "smtp_sasl_password_maps"
+#define DEF_SMTP_SASL_PASSWD   ""
+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"
 
index 4999f7b1c1ef667afc3dd2adaaca3cac0629ceff..17ef9f8b6f1b84b59bbe04fda1211cb5fc20cf2c 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Snapshot-20000418"
+#define DEF_MAIL_VERSION       "Snapshot-20000421"
 extern char *var_mail_version;
 
 /* LICENSE
index 316dfb19821c18370559f561214a51800d0fa8cb..a39f40d820932905d2ceca278386c101c8e7f18a 100644 (file)
@@ -45,7 +45,8 @@ typedef struct TOK822 {
 #define        TOK822_DOMLIT   259             /* stuff between [] not nesting */
 #define        TOK822_ADDR     260             /* actually a token 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
index f0456d03f6c0b17240c5c44eb0694521017c82bc..797deb3424e060638650046bf4189775a19b0291 100644 (file)
@@ -56,10 +56,13 @@ TOK822 *tok822_alloc(int type, const char *strval)
 {
     TOK822 *tp;
 
+#define CONTAINER_TOKEN(x) \
+       ((x) == TOK822_ADDR || (x) == TOK822_COMMENT || (x) == TOK822_STARTGRP)
+
     tp = (TOK822 *) mymalloc(sizeof(*tp));
     tp->type = type;
     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) :
                vstring_strcpy(vstring_alloc(strlen(strval) + 1), strval));
     return (tp);
index cd745cf966ccb423ef0eb5f3ae3a410d7c42842a..69827e846a1ccfb83244b03f4166530efa12093e 100644 (file)
@@ -191,8 +191,13 @@ VSTRING *tok822_internalize(VSTRING *vp, TOK822 *tree, int flags)
        case TOK822_ADDR:
            tok822_internalize(vp, tp->head, TOK822_STR_NONE);
            break;
-       case TOK822_ATOM:
        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:
            vstring_strcat(vp, vstring_str(tp->vstr));
            break;
@@ -242,7 +247,12 @@ VSTRING *tok822_externalize(VSTRING *vp, TOK822 *tree, int flags)
            vstring_strcat(vp, vstring_str(tp->vstr));
            break;
        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;
        case TOK822_QSTRING:
            VSTRING_ADDCH(vp, '"');
@@ -251,7 +261,7 @@ VSTRING *tok822_externalize(VSTRING *vp, TOK822 *tree, int flags)
            break;
        case TOK822_DOMLIT:
            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, ']');
            break;
        case TOK822_STARTGRP:
@@ -316,7 +326,6 @@ TOK822 *tok822_scan(const char *str, TOK822 **tailp)
            continue;
        if (ch == '(') {
            tp = tok822_alloc(TOK822_COMMENT, (char *) 0);
-           VSTRING_ADDCH(tp->vstr, ch);
            str = tok822_comment(tp, str);
        } else if (ch == '[') {
            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));
            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)
        *tailp = tail;
@@ -451,24 +466,36 @@ static void tok822_quote_atom(TOK822 *tp)
 
 const char *tok822_comment(TOK822 *tp, const char *str)
 {
+    TOK822 *tc = 0;
     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) {
-       VSTRING_ADDCH(tp->vstr, ISSPACE(ch) ? ' ' : ch);
        str++;
        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 == ')') {
            break;
-       } else if (ch == '\\') {
-           vstring_truncate(tp->vstr, VSTRING_LEN(tp->vstr) - 1);
-           if ((ch = *(unsigned char *) str) == 0)
-               break;
-           VSTRING_ADDCH(tp->vstr, ch);
-           str++;
+       } else {
+           if (ch == '\\') {
+               if ((ch = *(unsigned char *) str) == 0)
+                   break;
+               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);
 }
 
@@ -511,25 +538,36 @@ TOK822 *tok822_scan_addr(const char *addr)
 
 #ifdef TEST
 
+#include <unistd.h>
 #include <vstream.h>
 #include <vstring_vstream.h>
 
 /* 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) {
-       vstream_printf("%*s %s \"%c\"\n", indent, "", "OP", tp->type);
-    } else if (tp->type == TOK822_ADDR) {
-       vstream_printf("%*s %s\n", indent, "", "address");
-    } else {
-       vstream_printf("%*s %s \"%s\"\n", indent, "",
-                      tp->type == TOK822_COMMENT ? "comment" :
-                      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));
+    TOK822 *tp;
+
+    for (tp = list; tp; tp = tp->next) {
+       if (tp->type < TOK822_MINTOK) {
+           vstream_printf("%*s %s \"%c\"\n", indent, "", "OP", tp->type);
+       } else if (tp->type == TOK822_ADDR) {
+           vstream_printf("%*s %s\n", indent, "", "address");
+           tok822_print(tp->head, indent + 2);
+       } else if (tp->type == TOK822_COMMENT) {
+           vstream_printf("%*s %s\n", indent, "", "comment");
+           tok822_print(tp->head, indent + 2);
+       } 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);
     TOK822 *list;
-    TOK822 *tp;
-    TOK822 *ap;
-    int     indent = 0;
     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));
-       for (tp = list; tp; tp = tp->next) {
-           tok822_print(tp, indent);
-           if (tp->type == TOK822_ADDR) {
-               indent += 2;
-               for (ap = tp->head; ap; ap = ap->next)
-                   tok822_print(ap, indent);
-               indent -= 2;
-           }
-       }
+       vstream_printf("Parse tree:\n");
+       tok822_print(list, 0);
        vstream_printf("\n");
 
        vstream_printf("Internalized:\n%s\n\n",
diff --git a/postfix/global/tok822_parse.in b/postfix/global/tok822_parse.in
new file mode 100644 (file)
index 0000000..ebc564c
--- /dev/null
@@ -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;
diff --git a/postfix/global/tok822_parse.ref b/postfix/global/tok822_parse.ref
new file mode 100644 (file)
index 0000000..debfc9c
--- /dev/null
@@ -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;
+
index ddd7fad14b1c0990fb5542497294bdde286f386d..acad8c3aff986e789b7e67b3980276786f434f89 100644 (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="#backup">Configuring Postfix as backup MX host</a>
+
 </ul>
 
 <a name="remote_delivery"><h3>Remote delivery</h3>
@@ -1154,6 +1156,42 @@ host.
 
 <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>
 
 Every now and then, mail fails with "timed out while sending end
index f367ef9c1eb571f15e31a107a5090d5c34a99885..4d9338529ad7993e9b5bae2ed08704ab417a6ba5 100644 (file)
@@ -331,6 +331,7 @@ maildir.o: ../include/vstring.h
 maildir.o: ../include/make_dirs.h
 maildir.o: ../include/set_eugid.h
 maildir.o: ../include/get_hostname.h
+maildir.o: ../include/sane_fsops.h
 maildir.o: ../include/mail_copy.h
 maildir.o: ../include/bounce.h
 maildir.o: ../include/sent.h
index 4db9cb944b18cf458812ba8ee881d134a4c36304..48239ba6b36b8b9b893a7bae3bdc5287dbee4d05 100644 (file)
@@ -177,6 +177,7 @@ smtp_sasl_glue.o: ../include/msg.h
 smtp_sasl_glue.o: ../include/mymalloc.h
 smtp_sasl_glue.o: ../include/stringops.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/string_list.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/msg.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: ../include/vstream.h
 smtp_sasl_proto.o: ../include/vbuf.h
index 00d5ac1f73476745017def78887518f82dadf8ef..27a577d94d49e4cdf2105c9ec5c5935135d290db 100644 (file)
 /* .IP \fBsmtp_sasl_password_maps\fR
 /*     Lookup tables with per-host \fIname\fR:\fIpassword\fR entries.
 /*     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"
 /* .ad
 /* .fi
@@ -218,14 +232,10 @@ char   *var_fallback_relay;
 char   *var_bestmx_transp;
 char   *var_error_rcpt;
 int     var_smtp_always_ehlo;
-
-#ifdef USE_SASL_AUTH
-
-char   *var_smtp_sasl_pwd_maps;
+char   *var_smtp_sasl_opts;
+char   *var_smtp_sasl_passwd;
 bool    var_smtp_sasl_enable;
 
-#endif
-
  /*
   * Global variables. smtp_errno is set by the address lookup routines and by
   * 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_BESTMX_TRANSP, DEF_BESTMX_TRANSP, &var_bestmx_transp, 0, 0,
        VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0,
-#ifdef USE_SASL_AUTH
-       VAR_SMTP_SASL_PWD_MAPS, DEF_SMTP_SASL_PWD_MAPS, &var_smtp_sasl_pwd_maps, 0, 0,
-#endif
+       VAR_SMTP_SASL_PASSWD, DEF_SMTP_SASL_PASSWD, &var_smtp_sasl_passwd, 0, 0,
+       VAR_SMTP_SASL_OPTS, DEF_SMTP_SASL_OPTS, &var_smtp_sasl_opts, 0, 0,
        0,
     };
     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_SKIP_QUIT_RESP, DEF_SKIP_QUIT_RESP, &var_skip_quit_resp,
        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,
-#endif
        0,
     };
 
index 105904379b94263f0c75f1994482cc0ba1439b1c..f5841096563480711c2e804c03b59bee9a7fafc5 100644 (file)
@@ -91,6 +91,7 @@
 #include <mymalloc.h>
 #include <stringops.h>
 #include <split_at.h>
+#include <name_mask.h>
 
  /*
   * Global library
 
 #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.
   */
@@ -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,
                                      unsigned *len)
 {
+    char   *myname = "smtp_sasl_get_user";
     SMTP_STATE *state = (SMTP_STATE *) context;
 
     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;
     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,
                                        int id, sasl_secret_t **psecret)
 {
+    char   *myname = "smtp_sasl_get_passwd";
     SMTP_STATE *state = (SMTP_STATE *) context;
     int     len;
 
     if (msg_verbose)
-       msg_info("smtp_sasl_get_passwd: %s", state->sasl_passwd);
+       msg_info("%s: %s", myname, state->sasl_passwd);
 
     /*
      * Sanity check.
      */
     if (!conn || !psecret || id != SASL_CB_PASS)
        return (SASL_BADPARAM);
+    if (state->sasl_passwd == 0)
+       msg_panic("%s: no password looked up", myname);
 
     /*
      * 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'",
                     myname, state->session->host,
                     state->sasl_username, state->sasl_passwd);
-       return(1);
+       return (1);
     } else {
        if (msg_verbose)
            msg_info("%s: host `%s' no auth info found",
                     myname, state->session->host);
-       return(0);
+       return (0);
     }
 }
 
@@ -234,18 +258,23 @@ void    smtp_sasl_initialize(void)
      */
     if (smtp_sasl_passwd_map)
        msg_panic("smtp_sasl_initialize: repeated call");
-    if (*var_smtp_sasl_pwd_maps == 0)
-       msg_fatal("specify password table via the `%s' configuration parameter",
-                 VAR_SMTP_SASL_PWD_MAPS);
+    if (*var_smtp_sasl_passwd == 0)
+       msg_fatal("specify password table via the `%s' configuration parameter",
+                 VAR_SMTP_SASL_PASSWD);
 
     /*
      * Open the per-host password table and initialize the SASL library. Use
      * shared locks for reading, just in case someone updates the table.
      */
     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)
        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 */
@@ -291,7 +320,6 @@ void    smtp_sasl_start(SMTP_STATE *state)
                        state->sasl_callbacks, NULL_SECFLAGS,
                        (sasl_conn_t **) &state->sasl_conn) != SASL_OK)
        msg_fatal("per-session SASL client initialization");
-    smtp_sasl_passwd_lookup(state);
 
     /*
      * 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.max_ssf = 1;                     /* don't allow real SASL
                                                 * security layer */
-    sec_props.security_flags = 0;
+    sec_props.security_flags = smtp_sasl_sec_opts;
     sec_props.maxbufsize = 0;
     sec_props.property_names = 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) {
        vstring_sprintf(why, "cannot SASL authenticate to server %s: %s",
                        state->session->namaddr,
-                       sasl_errstring(result, NO_SASL_LANGLIST, 
+                       sasl_errstring(result, NO_SASL_LANGLIST,
                                       NO_SASL_OUTLANG));
        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
      * 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.
@@ -395,7 +423,7 @@ int     smtp_sasl_authenticate(SMTP_STATE *state, VSTRING *why)
        VSTRING_SPACE(state->sasl_decoded, serverinlen);
        if (sasl_decode64(line, serverinlen,
                        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);
            return (-1);
        }
@@ -407,8 +435,10 @@ int     smtp_sasl_authenticate(SMTP_STATE *state, VSTRING *why)
                                  STR(state->sasl_decoded), enc_length,
                            NO_SASL_INTERACTION, &clientout, &clientoutlen);
        if (result != SASL_OK && result != SASL_CONTINUE)
-           msg_warn("%s: smtp SASL authentication step failed",
-                    state->session->namaddr);
+           msg_warn("SASL authentication failed to server %s: %s",
+                    state->session->namaddr,
+                       sasl_errstring(result, NO_SASL_LANGLIST,
+                                      NO_SASL_OUTLANG));
 
        /*
         * Send a client response.
@@ -434,8 +464,8 @@ int     smtp_sasl_authenticate(SMTP_STATE *state, VSTRING *why)
      * We completed the authentication protocol.
      */
     if (resp->code / 100 != 2) {
-       vstring_sprintf(why, "unable to SASL authenticate with %s",
-                       state->session->namaddr);
+       vstring_sprintf(why, "SASL authentication failed; server %s said: %s",
+                       state->session->namaddr, resp->str);
        return (0);
     }
     return (1);
index 67b36092c791a82a45a450b40f7137c708b128be..3f2c7fc9fc516e410b942cd82ac1a2ec93ac6255 100644 (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/mymalloc.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/smtp_stream.h
 smtpd_sasl_glue.o: ../include/vstring.h
index d1f5c2c748c52f2e0f35c586174bbfdc11bb6aba..7b3c436e267c91906f40dc338b1acc807ddd2726 100644 (file)
 /*     Enable per-session authentication as per RFC 2554 (SASL).
 /*     This functionality is available only when explicitly selected
 /*     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
 /* .ad
 /* .fi
@@ -320,6 +334,7 @@ char   *var_local_rcpt_maps;
 bool    var_allow_untrust_route;
 int     var_smtpd_junk_cmd_limit;
 bool    var_smtpd_sasl_enable;
+char   *var_smtpd_sasl_opts;
 
  /*
   * 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_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_SMTPD_SASL_OPTS, DEF_SMTPD_SASL_OPTS, &var_smtpd_sasl_opts, 0, 0,
        0,
     };
 
index 8677106dc886060aa08c47f440efdd05c0fba302..a1d6eaa5bb7ef752be06c7856b9668946e07abbd 100644 (file)
@@ -768,19 +768,6 @@ static int reject_unknown_mailhost(SMTPD_STATE *state, char *name,
     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 */
 
 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);
 #ifdef USE_SASL_AUTH
        } 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
        } else if (strcasecmp(name, REJECT_UNKNOWN_RCPTDOM) == 0) {
            if (state->recipient)
index 5372e5c315d34c5034319e4f55b55c6f8a5809ab..a1ed45b5edd085957204aaf39cc5e413ca3adf48 100644 (file)
@@ -90,6 +90,7 @@
 #include <msg.h>
 #include <mymalloc.h>
 #include <namadr_list.h>
+#include <name_mask.h>
 
 /* Global library. */
 
@@ -140,6 +141,17 @@ static sasl_callback_t callbacks[] = {
     {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 */
 
 void    smtpd_sasl_initialize(void)
@@ -150,6 +162,11 @@ void    smtpd_sasl_initialize(void)
      */
     if (sasl_server_init(callbacks, "smtpd") != SASL_OK)
        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 */
@@ -195,7 +212,7 @@ void    smtpd_sasl_connect(SMTPD_STATE *state)
     sec_props.min_ssf = 0;
     sec_props.max_ssf = 1;                     /* don't allow real SASL
                                                 * security layer */
-    sec_props.security_flags = SASL_SEC_NOANONYMOUS;
+    sec_props.security_flags = smtpd_sasl_opts;
     sec_props.maxbufsize = 0;
     sec_props.property_names = 0;
     sec_props.property_values = 0;
index 89dce7643be3610d656935f3b670299a4ced9624..9bd793690bf5177cc9f226f5bc07b5d7514fd818 100644 (file)
@@ -16,6 +16,7 @@ extern void smtpd_sasl_connect(SMTPD_STATE *);
 extern void smtpd_sasl_disconnect(SMTPD_STATE *);
 extern char *smtpd_sasl_authenticate(SMTPD_STATE *, const char *, const char *);
 extern void smtpd_sasl_logout(SMTPD_STATE *);
+extern int permit_sasl_auth(SMTPD_STATE *, int, int);
 
 /* LICENSE
 /* .ad
index 05febfdb988cb54df15ba7d0c6f90b10bd25f554..5fc374d566ce2f37a2f9c7d7a717b246235435b7 100644 (file)
 /*
 /*     void    smtpd_sasl_mail_reset(state)
 /*     SMTPD_STATE *state;
+/*
+/*     static int permit_sasl_auth(state, authenticated, unauthenticated)
+/*     SMTPD_STATE *state;
+/*     int     authenticated;
+/*     int     unauthenticated;
 /* DESCRIPTION
 /*     This module contains random chunks of code that implement
 /*     the SMTP protocol interface for SASL negotiation. The goal
@@ -43,6 +48,9 @@
 /*     smtpd_sasl_mail_reset() performs cleanup for the SASL-specific
 /*     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:
 /* .IP state
 /*     SMTP session context.
 /* .IP sender
 /*     Sender address from the AUTH=sender option in the MAIL FROM
 /*     command.
+/* .IP authenticated
+/*     Result for authenticated client.
+/* .IP unauthenticated
+/*     Result for unauthenticated client.
 /* DIAGNOSTICS
 /*     All errors are fatal.
 /* 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